Beispiel #1
0
def GetBootImageTimestamp(boot_img):
    """
  Get timestamp from ramdisk within the boot image

  Args:
    boot_img: the boot image file. Ramdisk must be compressed with lz4 format.

  Return:
    An integer that corresponds to the timestamp of the boot image, or None
    if file has unknown format. Raise exception if an unexpected error has
    occurred.
  """

    tmp_dir = MakeTempDir('boot_', suffix='.img')
    try:
        RunAndCheckOutput(
            ['unpack_bootimg', '--boot_img', boot_img, '--out', tmp_dir])
        ramdisk = os.path.join(tmp_dir, 'ramdisk')
        if not os.path.isfile(ramdisk):
            logger.warning(
                'Unable to get boot image timestamp: no ramdisk in boot')
            return None
        uncompressed_ramdisk = os.path.join(tmp_dir, 'uncompressed_ramdisk')
        RunAndCheckOutput(['lz4', '-d', ramdisk, uncompressed_ramdisk])

        abs_uncompressed_ramdisk = os.path.abspath(uncompressed_ramdisk)
        extracted_ramdisk = MakeTempDir('extracted_ramdisk')
        # Use "toybox cpio" instead of "cpio" because the latter invokes cpio from
        # the host environment.
        RunAndCheckOutput(
            ['toybox', 'cpio', '-F', abs_uncompressed_ramdisk, '-i'],
            cwd=extracted_ramdisk)

        prop_file = None
        for search_path in RAMDISK_BUILD_PROP_REL_PATHS:
            prop_file = os.path.join(extracted_ramdisk, search_path)
            if os.path.isfile(prop_file):
                break
            logger.warning(
                'Unable to get boot image timestamp: no %s in ramdisk',
                search_path)

        if not prop_file:
            return None

        props = PartitionBuildProps.FromBuildPropFile('boot', prop_file)
        timestamp = props.GetProp('ro.bootimage.build.date.utc')
        if timestamp:
            return int(timestamp)
        logger.warning(
            'Unable to get boot image timestamp: ro.bootimage.build.date.utc is undefined'
        )
        return None

    except ExternalError as e:
        logger.warning('Unable to get boot image timestamp: %s', e)
        return None
Beispiel #2
0
def GetApexInfoFromTargetFiles(input_file, partition, compressed_only=True):
  """
  Get information about system APEX stored in the input_file zip

  Args:
    input_file: The filename of the target build target-files zip or directory.

  Return:
    A list of ota_metadata_pb2.ApexInfo() populated using the APEX stored in
    /system partition of the input_file
  """

  # Extract the apex files so that we can run checks on them
  if not isinstance(input_file, str):
    raise RuntimeError("must pass filepath to target-files zip or directory")

  apex_subdir = os.path.join(partition.upper(), 'apex')
  if os.path.isdir(input_file):
    tmp_dir = input_file
  else:
    tmp_dir = UnzipTemp(input_file, [os.path.join(apex_subdir, '*')])
  target_dir = os.path.join(tmp_dir, apex_subdir)

  # Partial target-files packages for vendor-only builds may not contain
  # a system apex directory.
  if not os.path.exists(target_dir):
    logger.info('No APEX directory at path: %s', target_dir)
    return []

  apex_infos = []

  debugfs_path = "debugfs"
  if OPTIONS.search_path:
    debugfs_path = os.path.join(OPTIONS.search_path, "bin", "debugfs_static")
  deapexer = 'deapexer'
  if OPTIONS.search_path:
    deapexer_path = os.path.join(OPTIONS.search_path, "bin", "deapexer")
    if os.path.isfile(deapexer_path):
      deapexer = deapexer_path
  for apex_filename in os.listdir(target_dir):
    apex_filepath = os.path.join(target_dir, apex_filename)
    if not os.path.isfile(apex_filepath) or \
            not zipfile.is_zipfile(apex_filepath):
      logger.info("Skipping %s because it's not a zipfile", apex_filepath)
      continue
    apex_info = ota_metadata_pb2.ApexInfo()
    # Open the apex file to retrieve information
    manifest = apex_manifest.fromApex(apex_filepath)
    apex_info.package_name = manifest.name
    apex_info.version = manifest.version
    # Check if the file is compressed or not
    apex_type = RunAndCheckOutput([
        deapexer, "--debugfs_path", debugfs_path,
        'info', '--print-type', apex_filepath]).rstrip()
    if apex_type == 'COMPRESSED':
      apex_info.is_compressed = True
    elif apex_type == 'UNCOMPRESSED':
      apex_info.is_compressed = False
    else:
      raise RuntimeError('Not an APEX file: ' + apex_type)

    # Decompress compressed APEX to determine its size
    if apex_info.is_compressed:
      decompressed_file_path = MakeTempFile(prefix="decompressed-",
                                            suffix=".apex")
      # Decompression target path should not exist
      os.remove(decompressed_file_path)
      RunAndCheckOutput([deapexer, 'decompress', '--input', apex_filepath,
                         '--output', decompressed_file_path])
      apex_info.decompressed_size = os.path.getsize(decompressed_file_path)

    if not compressed_only or apex_info.is_compressed:
      apex_infos.append(apex_info)

  return apex_infos