예제 #1
0
def main(argv):
    # def option_handler(o, a):
    #   return False

    args = common.ParseOptions(argv, __doc__)
    input_dir, output_dir = args

    OPTIONS.info_dict = common.LoadInfoDict(input_dir)

    # SPRD: add for secure boot
    OPTIONS.secure_boot = OPTIONS.info_dict.get("secure_boot", False)
    OPTIONS.secure_boot_tool = OPTIONS.info_dict.get("secure_boot_tool", None)
    OPTIONS.single_key = OPTIONS.info_dict.get("single_key", True)

    recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
                                           input_dir, "RECOVERY")
    boot_img = common.GetBootableImage("boot.img", "boot.img", input_dir,
                                       "BOOT")

    if not recovery_img or not boot_img:
        sys.exit(0)

    def output_sink(fn, data):
        with open(os.path.join(output_dir, "SYSTEM", *fn.split("/")),
                  "wb") as f:
            f.write(data)

    common.MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img)
예제 #2
0
def main(argv):
    args = common.ParseOptions(argv, __doc__)
    input_dir, output_dir = args

    common.InitLogging()

    OPTIONS.info_dict = common.LoadInfoDict(input_dir)

    recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
                                           input_dir, "RECOVERY")
    boot_img = common.GetBootableImage("boot.img", "boot.img", input_dir,
                                       "BOOT")

    if not recovery_img or not boot_img:
        sys.exit(0)

    board_uses_vendorimage = OPTIONS.info_dict.get(
        "board_uses_vendorimage") == "true"
    board_builds_vendorimage = OPTIONS.info_dict.get(
        "board_builds_vendorimage") == "true"
    target_files_dir = None

    if board_builds_vendorimage:
        target_files_dir = "VENDOR"
    elif not board_uses_vendorimage:
        target_files_dir = "SYSTEM/vendor"

    def output_sink(fn, data):
        if target_files_dir is None:
            return

        with open(os.path.join(output_dir, target_files_dir, *fn.split("/")),
                  "wb") as f:
            f.write(data)
예제 #3
0
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    for n in input_zip.namelist():
        if n.startswith("IMAGES/"):
            print "target_files appears to already contain images."
            sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip)
    if "selinux_fc" in OPTIONS.info_dict:
        OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp,
                                                       "BOOT", "RAMDISK",
                                                       "file_contexts")

    input_zip.close()
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED)

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    banner("boot")
    boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                         OPTIONS.input_tmp, "BOOT")
    if boot_image:
        boot_image.AddToZip(output_zip)

    banner("recovery")
    recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                             "recovery.img", OPTIONS.input_tmp,
                                             "RECOVERY")
    if recovery_image:
        recovery_image.AddToZip(output_zip)

    banner("system")
    AddSystem(output_zip)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    banner("userdata")
    AddUserdata(output_zip)
    banner("userdata_extra")
    AddUserdataExtra(output_zip)
    banner("cache")
    AddCache(output_zip)

    output_zip.close()
예제 #4
0
def WriteRawImages(info):
    print "WriteRawImages"
    image_info = LoadImageInfo(info.input_zip)

    if image_info is None:
        return

    fstab = info.info_dict["fstab"]
    try:
        bootareas_loc = fstab["/bootareas"].device
        fota_loc = fstab["/fota"].device
        flag_loc = fstab["/fota-flag"].device
    except KeyError:
        print "There is no bootareas/fota/fota-flag partition in recovery.fstab;"
    else:
        info.script.AppendExtra(('brcm.backup_bootareas("%s", "%s", "%s");') %
                                (bootareas_loc, fota_loc, flag_loc))

    for dir in sorted(image_info.keys()):
        image_name = image_info[dir]
        print "WriteRawImages,", dir, ":", image_name
        tmp_img = common.GetBootableImage(image_name, image_name,
                                          common.OPTIONS.input_tmp,
                                          "BOOTABLE_IMAGES")
        if tmp_img:
            common.ZipWriteStr(info.output_zip, image_name, tmp_img.data)
            info.script.WriteRawImage(dir, image_name)

    try:
        flag_loc = fstab["/fota-flag"].device
    except KeyError:
        print "There is no fota-flag partition in recovery.fstab;"
    else:
        info.script.AppendExtra(('brcm.clean_flag("%s");') % (flag_loc))
예제 #5
0
def main(argv):
    args = common.ParseOptions(argv, __doc__)
    input_dir, output_dir = args

    common.InitLogging()

    OPTIONS.info_dict = common.LoadInfoDict(input_dir)

    recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
                                           input_dir, "RECOVERY")
    boot_img = common.GetBootableImage("boot.img", "boot.img", input_dir,
                                       "BOOT")

    if not recovery_img or not boot_img:
        sys.exit(0)

    def output_sink(fn, data):
        with open(os.path.join(output_dir, "SYSTEM", *fn.split("/")),
                  "wb") as f:
            f.write(data)
예제 #6
0
def FullOTA_InstallEnd(info):
  # copy the vbmeta and dtbo into the package.
  try:
    vbmeta_img = common.GetBootableImage(
        "vbmeta.img", "vbmeta.img", OPTIONS.input_tmp, "VBMETA")
    dtbo_img = common.GetBootableImage(
        "dtbo.img", "dtbo.img", OPTIONS.input_tmp, "DTBO")
  except KeyError:
    print "no vbmeta or dtbo images in target_files; skipping install"
    return
  # copy the vbmeta into the package.
  common.ZipWriteStr(info.output_zip, "vbmeta.img", vbmeta_img.data)

  # emit the script code to trigger the vbmeta updater on the device
  info.script.WriteRawImage("/vbmeta", "vbmeta.img")

  # copy the dtbo into the package.
  common.ZipWriteStr(info.output_zip, "dtbo.img", dtbo_img.data)

  # emit the script code to trigger the dtbo updater on the device
  info.script.WriteRawImage("/dtbo", "dtbo.img")
예제 #7
0
def main(argv):
    bootable_only = [False]

    def option_handler(o, a):
        if o in ("-z", "--bootable_zip"):
            bootable_only[0] = True
        else:
            return False
        return True

    args = common.ParseOptions(argv,
                               __doc__,
                               extra_opts="z",
                               extra_long_opts=["bootable_zip"],
                               extra_option_handler=option_handler)

    bootable_only = bootable_only[0]

    if len(args) != 2:
        common.Usage(__doc__)
        sys.exit(1)

    OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
    output_zip = zipfile.ZipFile(args[1],
                                 "w",
                                 compression=zipfile.ZIP_DEFLATED,
                                 allowZip64=True)
    CopyInfo(output_zip)

    try:
        done = False
        images_path = os.path.join(OPTIONS.input_tmp, "IMAGES")
        if os.path.exists(images_path):
            # If this is a new target-files, it already contains the images,
            # and all we have to do is copy them to the output zip.
            images = os.listdir(images_path)
            if images:
                for i in images:
                    if bootable_only and i not in ("boot.img", "recovery.img"):
                        continue
                    if not i.endswith(".img"): continue
                    with open(os.path.join(images_path, i), "r") as f:
                        common.ZipWriteStr(output_zip, i, f.read())
                done = True

        if not done:
            # We have an old target-files that doesn't already contain the
            # images, so build them.
            import add_img_to_target_files

            OPTIONS.info_dict = common.LoadInfoDict(input_zip)

            # If this image was originally labelled with SELinux contexts,
            # make sure we also apply the labels in our new image. During
            # building, the "file_contexts" is in the out/ directory tree,
            # but for repacking from target-files.zip it's in the root
            # directory of the ramdisk.
            if "selinux_fc" in OPTIONS.info_dict:
                OPTIONS.info_dict["selinux_fc"] = os.path.join(
                    OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts")

            boot_image = common.GetBootableImage("boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
            if boot_image:
                boot_image.AddToZip(output_zip)
            recovery_image = common.GetBootableImage("recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
            if recovery_image:
                recovery_image.AddToZip(output_zip)

            def banner(s):
                print "\n\n++++ " + s + " ++++\n\n"

            if not bootable_only:
                banner("AddSystem")
                add_img_to_target_files.AddSystem(output_zip, prefix="")
                try:
                    input_zip.getinfo("VENDOR/")
                    banner("AddVendor")
                    add_img_to_target_files.AddVendor(output_zip, prefix="")
                except KeyError:
                    pass  # no vendor partition for this device
                try:
                    input_zip.getinfo("CUSTOM/")
                    banner("AddCustom")
                    add_img_to_target_files.AddCustom(output_zip, prefix="")
                except KeyError:
                    pass  # no custom partition for this device
                banner("AddUserdata")
                add_img_to_target_files.AddUserdata(output_zip, prefix="")
                banner("AddCache")
                add_img_to_target_files.AddCache(output_zip, prefix="")

    finally:
        print "cleaning up..."
        output_zip.close()
        shutil.rmtree(OPTIONS.input_tmp)

    print "done."
def AddImagesToTargetFiles(filename):
    """Creates and adds images (boot/recovery/system/...) to a target_files.zip.

  It works with either a zip file (zip mode), or a directory that contains the
  files to be packed into a target_files.zip (dir mode). The latter is used when
  being called from build/make/core/Makefile.

  The images will be created under IMAGES/ in the input target_files.zip.

  Args:
      filename: the target_files.zip, or the zip root directory.
  """
    if os.path.isdir(filename):
        OPTIONS.input_tmp = os.path.abspath(filename)
        input_zip = None
    else:
        OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
            print("target_files appears to already contain images.")
            sys.exit(1)

    # vendor.img is unlike system.img or system_other.img. Because it could be
    # built from source, or dropped into target_files.zip as a prebuilt blob. We
    # consider either of them as vendor.img being available, which could be used
    # when generating vbmeta.img for AVB.
    has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR"))
                  or os.path.exists(
                      os.path.join(OPTIONS.input_tmp, "IMAGES", "vendor.img")))
    has_system_other = os.path.isdir(
        os.path.join(OPTIONS.input_tmp, "SYSTEM_OTHER"))

    if input_zip:
        OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

        common.ZipClose(input_zip)
        output_zip = zipfile.ZipFile(filename,
                                     "a",
                                     compression=zipfile.ZIP_DEFLATED,
                                     allowZip64=True)
    else:
        OPTIONS.info_dict = common.LoadInfoDict(filename, filename)
        output_zip = None

    # Always make input_tmp/IMAGES available, since we may stage boot / recovery
    # images there even under zip mode. The directory will be cleaned up as part
    # of OPTIONS.input_tmp.
    images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
    if not os.path.isdir(images_dir):
        os.makedirs(images_dir)

    has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")

    # A map between partition names and their paths, which could be used when
    # generating AVB vbmeta image.
    partitions = dict()

    def banner(s):
        print("\n\n++++ " + s + " ++++\n\n")

    banner("boot")
    # common.GetBootableImage() returns the image directly if present.
    boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                         OPTIONS.input_tmp, "BOOT")
    # boot.img may be unavailable in some targets (e.g. aosp_arm64).
    if boot_image:
        partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                          "boot.img")
        if not os.path.exists(partitions['boot']):
            boot_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        assert recovery_image, "Failed to create recovery.img."
        partitions['recovery'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "recovery.img")
        if not os.path.exists(partitions['recovery']):
            recovery_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                recovery_image.AddToZip(output_zip)

            banner("recovery (two-step image)")
            # The special recovery.img for two-step package use.
            recovery_two_step_image = common.GetBootableImage(
                "IMAGES/recovery-two-step.img",
                "recovery-two-step.img",
                OPTIONS.input_tmp,
                "RECOVERY",
                two_step_image=True)
            assert recovery_two_step_image, "Failed to create recovery-two-step.img."
            recovery_two_step_image_path = os.path.join(
                OPTIONS.input_tmp, "IMAGES", "recovery-two-step.img")
            if not os.path.exists(recovery_two_step_image_path):
                recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
                if output_zip:
                    recovery_two_step_image.AddToZip(output_zip)

    banner("system")
    partitions['system'] = system_img_path = AddSystem(
        output_zip, recovery_img=recovery_image, boot_img=boot_image)

    if has_vendor:
        banner("vendor")
        partitions['vendor'] = vendor_img_path = AddVendor(output_zip)

    if has_system_other:
        banner("system_other")
        AddSystemOther(output_zip)

    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)

    if OPTIONS.info_dict.get("board_bpt_enable") == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    if OPTIONS.info_dict.get("has_dtbo") == "true":
        banner("dtbo")
        partitions['dtbo'] = AddDtbo(output_zip)

    if OPTIONS.info_dict.get("avb_enable") == "true":
        banner("vbmeta")
        AddVBMeta(output_zip, partitions)

    if OPTIONS.info_dict.get("avb_disabled_vbmeta") == "true":
        banner("vbmeta")
        AddDisabledVBMeta(output_zip)

    # For devices using A/B update, copy over images from RADIO/ and/or
    # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
    # images ready under IMAGES/. All images should have '.img' as extension.
    banner("radio")
    ab_partitions = os.path.join(OPTIONS.input_tmp, "META",
                                 "ab_partitions.txt")
    if os.path.exists(ab_partitions):
        with open(ab_partitions, 'r') as f:
            lines = f.readlines()
        # For devices using A/B update, generate care_map for system and vendor
        # partitions (if present), then write this file to target_files package.
        care_map_list = []
        for line in lines:
            if line.strip() == "system" and (
                    "system_verity_block_device" in OPTIONS.info_dict
                    or OPTIONS.info_dict.get("avb_system_hashtree_enable")
                    == "true"):
                assert os.path.exists(system_img_path)
                care_map_list += GetCareMap("system", system_img_path)
            if line.strip() == "vendor" and (
                    "vendor_verity_block_device" in OPTIONS.info_dict
                    or OPTIONS.info_dict.get("avb_vendor_hashtree_enable")
                    == "true"):
                assert os.path.exists(vendor_img_path)
                care_map_list += GetCareMap("vendor", vendor_img_path)

            img_name = line.strip() + ".img"
            prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
            if os.path.exists(prebuilt_path):
                print("%s already exists, no need to overwrite..." %
                      (img_name, ))
                continue

            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            img_vendor_dir = os.path.join(OPTIONS.input_tmp, "VENDOR_IMAGES")
            if os.path.exists(img_radio_path):
                if output_zip:
                    common.ZipWrite(output_zip, img_radio_path,
                                    os.path.join("IMAGES", img_name))
                else:
                    shutil.copy(img_radio_path, prebuilt_path)
            else:
                for root, _, files in os.walk(img_vendor_dir):
                    if img_name in files:
                        if output_zip:
                            common.ZipWrite(output_zip,
                                            os.path.join(root, img_name),
                                            os.path.join("IMAGES", img_name))
                        else:
                            shutil.copy(os.path.join(root, img_name),
                                        prebuilt_path)
                        break

            if output_zip:
                # Zip spec says: All slashes MUST be forward slashes.
                img_path = 'IMAGES/' + img_name
                assert img_path in output_zip.namelist(
                ), "cannot find " + img_name
            else:
                img_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
                assert os.path.exists(img_path), "cannot find " + img_name

        if care_map_list:
            care_map_path = "META/care_map.txt"
            if output_zip and care_map_path not in output_zip.namelist():
                common.ZipWriteStr(output_zip, care_map_path,
                                   '\n'.join(care_map_list))
            else:
                with open(os.path.join(OPTIONS.input_tmp, care_map_path),
                          'w') as fp:
                    fp.write('\n'.join(care_map_list))
                if output_zip:
                    OPTIONS.replace_updated_files_list.append(care_map_path)

    # Radio images that need to be packed into IMAGES/, and product-img.zip.
    pack_radioimages = os.path.join(OPTIONS.input_tmp, "META",
                                    "pack_radioimages.txt")
    if os.path.exists(pack_radioimages):
        with open(pack_radioimages, 'r') as f:
            lines = f.readlines()
        for line in lines:
            img_name = line.strip()
            _, ext = os.path.splitext(img_name)
            if not ext:
                img_name += ".img"
            prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
            if os.path.exists(prebuilt_path):
                print("%s already exists, no need to overwrite..." %
                      (img_name, ))
                continue

            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            assert os.path.exists(img_radio_path), \
                "Failed to find %s at %s" % (img_name, img_radio_path)
            if output_zip:
                common.ZipWrite(output_zip, img_radio_path,
                                os.path.join("IMAGES", img_name))
            else:
                shutil.copy(img_radio_path, prebuilt_path)

    if output_zip:
        common.ZipClose(output_zip)
        if OPTIONS.replace_updated_files_list:
            ReplaceUpdatedFiles(output_zip.filename,
                                OPTIONS.replace_updated_files_list)
예제 #9
0
def WriteFullOTAPackage(input_zip, output_zip):
    # TODO: how to determine this?  We don't know what version it will
    # be installed on top of.  For now, we expect the API just won't
    # change very often.
    script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)

    if OPTIONS.override_prop:
        metadata = {
            "post-timestamp": GetBuildProp("ro.build.date.utc",
                                           OPTIONS.info_dict),
        }
    else:
        metadata = {
            "post-build": GetBuildProp("ro.build.fingerprint",
                                       OPTIONS.info_dict),
            "pre-device": GetBuildProp("ro.product.device", OPTIONS.info_dict),
            "post-timestamp": GetBuildProp("ro.build.date.utc",
                                           OPTIONS.info_dict),
        }

    device_specific = common.DeviceSpecificParams(
        input_zip=input_zip,
        input_version=OPTIONS.info_dict["recovery_api_version"],
        output_zip=output_zip,
        script=script,
        input_tmp=OPTIONS.input_tmp,
        metadata=metadata,
        info_dict=OPTIONS.info_dict)

    #if not OPTIONS.omit_prereq:
    #  ts = GetBuildProp("ro.build.date.utc", OPTIONS.info_dict)
    #  ts_text = GetBuildProp("ro.build.date", OPTIONS.info_dict)
    #  script.AssertOlderBuild(ts, ts_text)

    AppendAssertions(script, OPTIONS.info_dict)
    device_specific.FullOTA_Assertions()
    device_specific.FullOTA_InstallBegin()

    if OPTIONS.backuptool:
        script.Mount("/system")
        script.RunBackup("backup")
        script.Unmount("/system")

    script.ShowProgress(0.5, 0)

    if OPTIONS.wipe_user_data:
        script.FormatPartition("/data")

    if "selinux_fc" in OPTIONS.info_dict:
        WritePolicyConfig(OPTIONS.info_dict["selinux_fc"], output_zip)

    script.FormatPartition("/system")
    script.Mount("/system")
    #script.UnpackPackageDir("recovery", "/system")
    script.UnpackPackageDir("system", "/system")

    symlinks = CopySystemFiles(input_zip, output_zip)
    script.MakeSymlinks(symlinks)

    boot_img = common.GetBootableImage("boot.img", "boot.img",
                                       OPTIONS.input_tmp, "BOOT")
    #recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
    #                                       OPTIONS.input_tmp, "RECOVERY")
    #MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)

    Item.GetMetadata(input_zip)
    Item.Get("system").SetPermissions(script)

    common.CheckSize(boot_img.data, "boot.img", OPTIONS.info_dict)
    common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
    script.ShowProgress(0.2, 0)

    if OPTIONS.backuptool:
        script.ShowProgress(0.2, 10)
        script.RunBackup("restore")

    script.ShowProgress(0.2, 10)
    script.WriteRawImage("/boot", "boot.img")

    script.ShowProgress(0.1, 0)
    device_specific.FullOTA_InstallEnd()

    if OPTIONS.extra_script is not None:
        script.AppendExtra(OPTIONS.extra_script)

    script.UnmountAll()
    script.AddToZip(input_zip, output_zip)
    WriteMetadata(metadata, output_zip)
예제 #10
0
def AddImagesToTargetFiles(filename):
    """Creates and adds images (boot/recovery/system/...) to a target_files.zip.

  It works with either a zip file (zip mode), or a directory that contains the
  files to be packed into a target_files.zip (dir mode). The latter is used when
  being called from build/make/core/Makefile.

  The images will be created under IMAGES/ in the input target_files.zip.

  Args:
    filename: the target_files.zip, or the zip root directory.
  """
    if os.path.isdir(filename):
        OPTIONS.input_tmp = os.path.abspath(filename)
    else:
        OPTIONS.input_tmp = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
            logger.warning("target_files appears to already contain images.")
            sys.exit(1)

    OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp, repacking=True)

    has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"
    has_boot = OPTIONS.info_dict.get("no_boot") != "true"
    has_vendor_boot = OPTIONS.info_dict.get("vendor_boot") == "true"

    # {vendor,odm,product,system_ext,vendor_dlkm,odm_dlkm, system, system_other}.img
    # can be built from source, or  dropped into target_files.zip as a prebuilt blob.
    has_vendor = HasPartition("vendor")
    has_odm = HasPartition("odm")
    has_vendor_dlkm = HasPartition("vendor_dlkm")
    has_odm_dlkm = HasPartition("odm_dlkm")
    has_product = HasPartition("product")
    has_system_ext = HasPartition("system_ext")
    has_system = HasPartition("system")
    has_system_other = HasPartition("system_other")
    has_userdata = OPTIONS.info_dict.get("building_userdata_image") == "true"
    has_cache = OPTIONS.info_dict.get("building_cache_image") == "true"

    # Set up the output destination. It writes to the given directory for dir
    # mode; otherwise appends to the given ZIP.
    if os.path.isdir(filename):
        output_zip = None
    else:
        output_zip = zipfile.ZipFile(filename,
                                     "a",
                                     compression=zipfile.ZIP_DEFLATED,
                                     allowZip64=True)

    # Always make input_tmp/IMAGES available, since we may stage boot / recovery
    # images there even under zip mode. The directory will be cleaned up as part
    # of OPTIONS.input_tmp.
    images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
    if not os.path.isdir(images_dir):
        os.makedirs(images_dir)

    # A map between partition names and their paths, which could be used when
    # generating AVB vbmeta image.
    partitions = {}

    def banner(s):
        logger.info("\n\n++++ %s  ++++\n\n", s)

    boot_image = None
    if has_boot:
        banner("boot")
        boot_images = OPTIONS.info_dict.get("boot_images")
        if boot_images is None:
            boot_images = "boot.img"
        for index, b in enumerate(boot_images.split()):
            # common.GetBootableImage() returns the image directly if present.
            boot_image = common.GetBootableImage("IMAGES/" + b, b,
                                                 OPTIONS.input_tmp, "BOOT")
            # boot.img may be unavailable in some targets (e.g. aosp_arm64).
            if boot_image:
                boot_image_path = os.path.join(OPTIONS.input_tmp, "IMAGES", b)
                # Although multiple boot images can be generated, include the image
                # descriptor of only the first boot image in vbmeta
                if index == 0:
                    partitions['boot'] = boot_image_path
                if not os.path.exists(boot_image_path):
                    boot_image.WriteToDir(OPTIONS.input_tmp)
                    if output_zip:
                        boot_image.AddToZip(output_zip)

    if has_vendor_boot:
        banner("vendor_boot")
        vendor_boot_image = common.GetVendorBootImage("IMAGES/vendor_boot.img",
                                                      "vendor_boot.img",
                                                      OPTIONS.input_tmp,
                                                      "VENDOR_BOOT")
        if vendor_boot_image:
            partitions['vendor_boot'] = os.path.join(OPTIONS.input_tmp,
                                                     "IMAGES",
                                                     "vendor_boot.img")
            if not os.path.exists(partitions['vendor_boot']):
                vendor_boot_image.WriteToDir(OPTIONS.input_tmp)
                if output_zip:
                    vendor_boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        assert recovery_image, "Failed to create recovery.img."
        partitions['recovery'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "recovery.img")
        if not os.path.exists(partitions['recovery']):
            recovery_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                recovery_image.AddToZip(output_zip)

            banner("recovery (two-step image)")
            # The special recovery.img for two-step package use.
            recovery_two_step_image = common.GetBootableImage(
                "OTA/recovery-two-step.img",
                "recovery-two-step.img",
                OPTIONS.input_tmp,
                "RECOVERY",
                two_step_image=True)
            assert recovery_two_step_image, "Failed to create recovery-two-step.img."
            recovery_two_step_image_path = os.path.join(
                OPTIONS.input_tmp, "OTA", "recovery-two-step.img")
            if not os.path.exists(recovery_two_step_image_path):
                recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
                if output_zip:
                    recovery_two_step_image.AddToZip(output_zip)

    if has_system:
        banner("system")
        partitions['system'] = AddSystem(output_zip,
                                         recovery_img=recovery_image,
                                         boot_img=boot_image)

    if has_vendor:
        banner("vendor")
        partitions['vendor'] = AddVendor(output_zip,
                                         recovery_img=recovery_image,
                                         boot_img=boot_image)

    if has_product:
        banner("product")
        partitions['product'] = AddProduct(output_zip)

    if has_system_ext:
        banner("system_ext")
        partitions['system_ext'] = AddSystemExt(output_zip)

    if has_odm:
        banner("odm")
        partitions['odm'] = AddOdm(output_zip)

    if has_vendor_dlkm:
        banner("vendor_dlkm")
        partitions['vendor_dlkm'] = AddVendorDlkm(output_zip)

    if has_odm_dlkm:
        banner("odm_dlkm")
        partitions['odm_dlkm'] = AddOdmDlkm(output_zip)

    if has_system_other:
        banner("system_other")
        AddSystemOther(output_zip)

    AddApexInfo(output_zip)

    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)
        banner("cache")
        AddCache(output_zip)

    if OPTIONS.info_dict.get("board_bpt_enable") == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    if OPTIONS.info_dict.get("has_dtbo") == "true":
        banner("dtbo")
        partitions['dtbo'] = AddDtbo(output_zip)

    if OPTIONS.info_dict.get("has_pvmfw") == "true":
        banner("pvmfw")
        partitions['pvmfw'] = AddPvmfw(output_zip)

    # Custom images.
    custom_partitions = OPTIONS.info_dict.get(
        "avb_custom_images_partition_list", "").strip().split()
    for partition_name in custom_partitions:
        partition_name = partition_name.strip()
        banner("custom images for " + partition_name)
        partitions[partition_name] = AddCustomImages(output_zip,
                                                     partition_name)

    if OPTIONS.info_dict.get("avb_enable") == "true":
        # vbmeta_partitions includes the partitions that should be included into
        # top-level vbmeta.img, which are the ones that are not included in any
        # chained VBMeta image plus the chained VBMeta images themselves.
        # Currently custom_partitions are all chained to VBMeta image.
        vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions)

        vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip()
        if vbmeta_system:
            banner("vbmeta_system")
            partitions["vbmeta_system"] = AddVBMeta(output_zip, partitions,
                                                    "vbmeta_system",
                                                    vbmeta_system.split())
            vbmeta_partitions = [
                item for item in vbmeta_partitions
                if item not in vbmeta_system.split()
            ]
            vbmeta_partitions.append("vbmeta_system")

        vbmeta_vendor = OPTIONS.info_dict.get("avb_vbmeta_vendor", "").strip()
        if vbmeta_vendor:
            banner("vbmeta_vendor")
            partitions["vbmeta_vendor"] = AddVBMeta(output_zip, partitions,
                                                    "vbmeta_vendor",
                                                    vbmeta_vendor.split())
            vbmeta_partitions = [
                item for item in vbmeta_partitions
                if item not in vbmeta_vendor.split()
            ]
            vbmeta_partitions.append("vbmeta_vendor")

        if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true":
            banner("vbmeta")
            AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)

    if OPTIONS.info_dict.get("use_dynamic_partitions") == "true":
        if OPTIONS.info_dict.get("build_super_empty_partition") == "true":
            banner("super_empty")
            AddSuperEmpty(output_zip)

    if OPTIONS.info_dict.get("build_super_partition") == "true":
        if OPTIONS.info_dict.get(
                "build_retrofit_dynamic_partitions_ota_package") == "true":
            banner("super split images")
            AddSuperSplit(output_zip)

    banner("radio")
    ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                     "ab_partitions.txt")
    if os.path.exists(ab_partitions_txt):
        with open(ab_partitions_txt) as f:
            ab_partitions = f.readlines()

        # For devices using A/B update, make sure we have all the needed images
        # ready under IMAGES/ or RADIO/.
        CheckAbOtaImages(output_zip, ab_partitions)

        # Generate care_map.pb for ab_partitions, then write this file to
        # target_files package.
        output_care_map = os.path.join(OPTIONS.input_tmp, "META",
                                       "care_map.pb")
        AddCareMapForAbOta(output_zip if output_zip else output_care_map,
                           ab_partitions, partitions)

    # Radio images that need to be packed into IMAGES/, and product-img.zip.
    pack_radioimages_txt = os.path.join(OPTIONS.input_tmp, "META",
                                        "pack_radioimages.txt")
    if os.path.exists(pack_radioimages_txt):
        with open(pack_radioimages_txt) as f:
            AddPackRadioImages(output_zip, f.readlines())

    # Calculate the vbmeta digest and put the result in to META/
    boot_images = OPTIONS.info_dict.get("boot_images")
    # Disable the digest calculation if the target_file is used as a container
    # for boot images.
    boot_container = boot_images and len(boot_images.split()) >= 2
    if (OPTIONS.info_dict.get("avb_enable") == "true" and not boot_container
            and OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true"):
        avbtool = OPTIONS.info_dict["avb_avbtool"]
        digest = verity_utils.CalculateVbmetaDigest(OPTIONS.input_tmp, avbtool)
        vbmeta_digest_txt = os.path.join(OPTIONS.input_tmp, "META",
                                         "vbmeta_digest.txt")
        with open(vbmeta_digest_txt, 'w') as f:
            f.write(digest)

    if output_zip:
        common.ZipClose(output_zip)
        if OPTIONS.replace_updated_files_list:
            ReplaceUpdatedFiles(output_zip.filename,
                                OPTIONS.replace_updated_files_list)
예제 #11
0
def WriteFullOTAPackage(input_zip, output_file):
  target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)

  # We don't know what version it will be installed on top of. We expect the API
  # just won't change very often. Similarly for fstab, it might have changed in
  # the target build.
  target_api_version = target_info["recovery_api_version"]
  script = edify_generator.EdifyGenerator(target_api_version, target_info)

  if target_info.oem_props and not OPTIONS.oem_no_mount:
    target_info.WriteMountOemScript(script)

  metadata = GetPackageMetadata(target_info)

  if not OPTIONS.no_signing:
    staging_file = common.MakeTempFile(suffix='.zip')
  else:
    staging_file = output_file

  output_zip = zipfile.ZipFile(
      staging_file, "w", compression=zipfile.ZIP_DEFLATED)

  device_specific = common.DeviceSpecificParams(
      input_zip=input_zip,
      input_version=target_api_version,
      output_zip=output_zip,
      script=script,
      input_tmp=OPTIONS.input_tmp,
      metadata=metadata,
      info_dict=OPTIONS.info_dict)

  assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)

  # Assertions (e.g. downgrade check, device properties check).
  #ts = target_info.GetBuildProp("ro.build.date.utc")
  #ts_text = target_info.GetBuildProp("ro.build.date")
  #script.AssertOlderBuild(ts, ts_text)

  target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
  device_specific.FullOTA_Assertions()

  block_diff_dict = GetBlockDifferences(target_zip=input_zip, source_zip=None,
                                        target_info=target_info,
                                        source_info=None,
                                        device_specific=device_specific)

  # Two-step package strategy (in chronological order, which is *not*
  # the order in which the generated script has things):
  #
  # if stage is not "2/3" or "3/3":
  #    write recovery image to boot partition
  #    set stage to "2/3"
  #    reboot to boot partition and restart recovery
  # else if stage is "2/3":
  #    write recovery image to recovery partition
  #    set stage to "3/3"
  #    reboot to recovery partition and restart recovery
  # else:
  #    (stage must be "3/3")
  #    set stage to ""
  #    do normal full package installation:
  #       wipe and install system, boot image, etc.
  #       set up system to update recovery partition on first boot
  #    complete script normally
  #    (allow recovery to mark itself finished and reboot)

  #recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
  #                                       OPTIONS.input_tmp, "RECOVERY")
  if OPTIONS.two_step:
    if not target_info.get("multistage_support"):
      assert False, "two-step packages not supported by this build"
    fs = target_info["fstab"]["/misc"]
    assert fs.fs_type.upper() == "EMMC", \
        "two-step packages only supported on devices with EMMC /misc partitions"
    bcb_dev = {"bcb_dev": fs.device}
    common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
    script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
    script.Comment("Stage 2/3")
    #script.WriteRawImage("/recovery", "recovery.img")
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") == "3/3" then
""" % bcb_dev)

    # Stage 3/3: Make changes.
    script.Comment("Stage 3/3")

  # Dump fingerprints
  script.Print("Target: {}".format(target_info.fingerprint))

  androidver = target_info.GetBuildProp("ro.build.version.release")
  buildid = target_info.GetBuildProp("ro.build.id")
  builddate = target_info.GetBuildProp("ro.build.date")
  securep = target_info.GetBuildProp("ro.build.version.security_patch")
  name = target_info.GetBuildProp("ro.product.name")
  model = target_info.GetBuildProp("ro.product.model")
  manufacturer = target_info.GetBuildProp("ro.product.manufacturer")
  builduser = target_info.GetBuildProp("ro.build.user")
  buildsdk = target_info.GetBuildProp("ro.build.version.sdk")

  # Start output
  script.Print("----------------------------------------------")
  script.Print("           _____ _   _             _   _ ___ ")
  script.Print("  _____  _|_   _| | | |_ __ ___   | | | |_ _|")
  script.Print(" / _ \ \/ / | | | |_| | '_ ` _ \  | | | || |")
  script.Print("|  __/>  <  | | |  _  | | | | | | | |_| || |")
  script.Print(" \___/_/\_\ |_| |_| |_|_| |_| |_|  \___/|___|")
  script.Print("")
  script.Print("         extended TouHou modified UI")
  script.Print("            Based on AOSP")
  script.Print("----------------------------------------------")
  script.Print("ROM Information    :")
  script.Print("Build Date         : %s"%(builddate))
  script.Print("Android Version    : %s"%(androidver))
  script.Print("exTHmUI Version    : %s"%(buildid))
  script.Print("SDK Version        : %s"%(buildsdk))
  script.Print("Security Patch Date: %s"%(securep))
  script.Print("----------------------------------------------")
  script.Print("Device Information :")
  script.Print("Manufacturer       : %s"%(manufacturer))
  script.Print("Name               : %s"%(name))
  script.Print("Model              : %s"%(model))
  script.Print("----------------------------------------------")
  script.Print("Installing exTHmUI to your device...")
  script.Print("")
  device_specific.FullOTA_InstallBegin()

  CopyInstallTools(output_zip)
  script.UnpackPackageDir("install", "/tmp/install")
  script.SetPermissionsRecursive("/tmp/install", 0, 0, 0o755, 0o644, None, None)
  script.SetPermissionsRecursive("/tmp/install/bin", 0, 0, 0o755, 0o755, None, None)

  if target_info.get("system_root_image") == "true":
    sysmount = "/"
  else:
    sysmount = "/system"

  if OPTIONS.backuptool:
    script.RunBackup("backup", sysmount, target_info.get('use_dynamic_partitions') == "true")

  # All other partitions as well as the data wipe use 10% of the progress, and
  # the update of the system partition takes the remaining progress.
  system_progress = 0.9 - (len(block_diff_dict) - 1) * 0.1
  if OPTIONS.wipe_user_data:
    system_progress -= 0.1
  progress_dict = {partition: 0.1 for partition in block_diff_dict}
  progress_dict["system"] = system_progress

  if target_info.get('use_dynamic_partitions') == "true":
    # Use empty source_info_dict to indicate that all partitions / groups must
    # be re-added.
    dynamic_partitions_diff = common.DynamicPartitionsDifference(
        info_dict=OPTIONS.info_dict,
        block_diffs=block_diff_dict.values(),
        progress_dict=progress_dict,
        build_without_vendor=(not HasPartition(input_zip, "vendor")))
    dynamic_partitions_diff.WriteScript(script, output_zip,
                                        write_verify_script=OPTIONS.verify)
  else:
    for block_diff in block_diff_dict.values():
      block_diff.WriteScript(script, output_zip,
                             progress=progress_dict.get(block_diff.partition),
                             write_verify_script=OPTIONS.verify)

  CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info)

  boot_img = common.GetBootableImage(
      "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
  common.CheckSize(boot_img.data, "boot.img", target_info)
  common.ZipWriteStr(output_zip, "boot.img", boot_img.data)

  device_specific.FullOTA_PostValidate()

  if OPTIONS.backuptool:
    script.ShowProgress(0.02, 10)
    script.RunBackup("restore", sysmount, target_info.get('use_dynamic_partitions') == "true")

  script.WriteRawImage("/boot", "boot.img")

  script.ShowProgress(0.1, 10)
  device_specific.FullOTA_InstallEnd()

  if OPTIONS.extra_script is not None:
    script.AppendExtra(OPTIONS.extra_script)

  script.UnmountAll()

  if OPTIONS.wipe_user_data:
    script.ShowProgress(0.1, 10)
    script.FormatPartition("/data")

  if OPTIONS.two_step:
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
""" % bcb_dev)
    script.AppendExtra("else\n")

    # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot.
    script.Comment("Stage 1/3")
    _WriteRecoveryImageToBoot(script, output_zip)

    script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

  script.SetProgress(1)
  script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
  metadata.required_cache = script.required_cache

  # We haven't written the metadata entry, which will be done in
  # FinalizeMetadata.
  common.ZipClose(output_zip)

  needed_property_files = (
      NonAbOtaPropertyFiles(),
  )
  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
예제 #12
0
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, apk_key_map,
                       key_passwords, platform_api_level,
                       codename_to_api_level_map):

    maxsize = max([
        len(os.path.basename(i.filename)) for i in input_tf_zip.infolist()
        if i.filename.endswith('.apk')
    ])
    rebuild_recovery = False

    tmpdir = tempfile.mkdtemp()

    def write_to_temp(fn, attr, data):
        fn = os.path.join(tmpdir, fn)
        if fn.endswith("/"):
            fn = os.path.join(tmpdir, fn)
            os.mkdir(fn)
        else:
            d = os.path.dirname(fn)
            if d and not os.path.exists(d):
                os.makedirs(d)

            if attr >> 16 == 0xa1ff:
                os.symlink(data, fn)
            else:
                with open(fn, "wb") as f:
                    f.write(data)

    for info in input_tf_zip.infolist():
        if info.filename.startswith("IMAGES/"):
            continue

        data = input_tf_zip.read(info.filename)
        out_info = copy.copy(info)

        # Replace keys if requested.
        if (info.filename == "META/misc_info.txt"
                and OPTIONS.replace_verity_private_key):
            ReplaceVerityPrivateKey(input_tf_zip, output_tf_zip, misc_info,
                                    OPTIONS.replace_verity_private_key[1])
        elif (info.filename in ("BOOT/RAMDISK/verity_key", "BOOT/verity_key")
              and OPTIONS.replace_verity_public_key):
            new_data = ReplaceVerityPublicKey(
                output_tf_zip, info.filename,
                OPTIONS.replace_verity_public_key[1])
            write_to_temp(info.filename, info.external_attr, new_data)
        # Copy BOOT/, RECOVERY/, META/, ROOT/ to rebuild recovery patch.
        elif (info.filename.startswith("BOOT/")
              or info.filename.startswith("RECOVERY/")
              or info.filename.startswith("META/")
              or info.filename.startswith("ROOT/")
              or info.filename == "SYSTEM/etc/recovery-resource.dat"):
            write_to_temp(info.filename, info.external_attr, data)

        # Sign APKs.
        if info.filename.endswith(".apk"):
            name = os.path.basename(info.filename)
            key = apk_key_map[name]
            if key not in common.SPECIAL_CERT_STRINGS:
                print "    signing: %-*s (%s)" % (maxsize, name, key)
                signed_data = SignApk(data, key, key_passwords[key],
                                      platform_api_level,
                                      codename_to_api_level_map)
                common.ZipWriteStr(output_tf_zip, out_info, signed_data)
            else:
                # an APK we're not supposed to sign.
                print "NOT signing: %s" % (name, )
                common.ZipWriteStr(output_tf_zip, out_info, data)
        elif info.filename in ("SYSTEM/build.prop", "VENDOR/build.prop",
                               "BOOT/RAMDISK/default.prop",
                               "RECOVERY/RAMDISK/default.prop"):
            print "rewriting %s:" % (info.filename, )
            new_data = RewriteProps(data, misc_info)
            common.ZipWriteStr(output_tf_zip, out_info, new_data)
            if info.filename in ("BOOT/RAMDISK/default.prop",
                                 "RECOVERY/RAMDISK/default.prop"):
                write_to_temp(info.filename, info.external_attr, new_data)
        elif info.filename.endswith("mac_permissions.xml"):
            print "rewriting %s with new keys." % (info.filename, )
            new_data = ReplaceCerts(data)
            common.ZipWriteStr(output_tf_zip, out_info, new_data)
        elif info.filename in ("SYSTEM/recovery-from-boot.p",
                               "SYSTEM/etc/recovery.img",
                               "SYSTEM/bin/install-recovery.sh"):
            rebuild_recovery = True
        elif (OPTIONS.replace_ota_keys
              and info.filename in ("RECOVERY/RAMDISK/res/keys",
                                    "SYSTEM/etc/security/otacerts.zip")):
            # don't copy these files if we're regenerating them below
            pass
        elif (OPTIONS.replace_verity_private_key
              and info.filename == "META/misc_info.txt"):
            pass
        elif (OPTIONS.replace_verity_public_key and info.filename
              in ("BOOT/RAMDISK/verity_key", "BOOT/verity_key")):
            pass
        else:
            # a non-APK file; copy it verbatim
            common.ZipWriteStr(output_tf_zip, out_info, data)

    if OPTIONS.replace_ota_keys:
        new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip,
                                           misc_info)
        if new_recovery_keys:
            write_to_temp("RECOVERY/RAMDISK/res/keys", 0o755 << 16,
                          new_recovery_keys)

    if rebuild_recovery:
        recovery_img = common.GetBootableImage("recovery.img",
                                               "recovery.img",
                                               tmpdir,
                                               "RECOVERY",
                                               info_dict=misc_info)
        boot_img = common.GetBootableImage("boot.img",
                                           "boot.img",
                                           tmpdir,
                                           "BOOT",
                                           info_dict=misc_info)

        def output_sink(fn, data):
            common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data)

        common.MakeRecoveryPatch(tmpdir,
                                 output_sink,
                                 recovery_img,
                                 boot_img,
                                 info_dict=misc_info)

    shutil.rmtree(tmpdir)
예제 #13
0
def main(argv):
    bootable_only = [False]

    def option_handler(o, _):
        if o in ("-z", "--bootable_zip"):
            bootable_only[0] = True
        else:
            return False
        return True

    args = common.ParseOptions(argv,
                               __doc__,
                               extra_opts="z",
                               extra_long_opts=["bootable_zip"],
                               extra_option_handler=option_handler)

    bootable_only = bootable_only[0]

    if len(args) != 2:
        common.Usage(__doc__)
        sys.exit(1)

    OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
    output_zip = zipfile.ZipFile(args[1],
                                 "w",
                                 compression=zipfile.ZIP_DEFLATED)
    CopyInfo(output_zip)
    AddRadio(output_zip)

    try:
        done = False
        images_path = os.path.join(OPTIONS.input_tmp, "IMAGES")
        if os.path.exists(images_path):
            # If this is a new target-files, it already contains the images,
            # and all we have to do is copy them to the output zip.
            # Skip oem.img files since they are not needed in fastboot images.
            images = os.listdir(images_path)
            if images:
                for image in images:
                    if bootable_only and image not in ("boot.img",
                                                       "recovery.img"):
                        continue
                    if not image.endswith(".img"):
                        continue
                    if image == "oem.img" or image == "recovery-two-step.img":
                        continue
                    common.ZipWrite(output_zip,
                                    os.path.join(images_path, image), image)
                done = True

        if not done:
            # We have an old target-files that doesn't already contain the
            # images, so build them.
            import add_img_to_target_files

            OPTIONS.info_dict = common.LoadInfoDict(input_zip,
                                                    OPTIONS.input_tmp)

            boot_image = common.GetBootableImage("boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
            if boot_image:
                boot_image.AddToZip(output_zip)

            if OPTIONS.info_dict.get("no_recovery") != "true":
                recovery_image = common.GetBootableImage(
                    "recovery.img", "recovery.img", OPTIONS.input_tmp,
                    "RECOVERY")
                if recovery_image:
                    recovery_image.AddToZip(output_zip)

            def banner(s):
                print("\n\n++++ " + s + " ++++\n\n")

            if not bootable_only:
                banner("AddSystem")
                add_img_to_target_files.AddSystem(output_zip, prefix="")
                try:
                    input_zip.getinfo("VENDOR/")
                    banner("AddVendor")
                    add_img_to_target_files.AddVendor(output_zip, prefix="")
                except KeyError:
                    pass  # no vendor partition for this device
                banner("AddUserdata")
                add_img_to_target_files.AddUserdata(output_zip, prefix="")
                banner("AddUserdataExtra")
                add_img_to_target_files.AddUserdataExtra(output_zip, prefix="")
                banner("AddCache")
                add_img_to_target_files.AddCache(output_zip, prefix="")

    finally:
        print("cleaning up...")
        common.ZipClose(output_zip)
        shutil.rmtree(OPTIONS.input_tmp)

    print("done.")
    new_data = ReplaceVerityPublicKey(
        output_tf_zip, dest, OPTIONS.replace_verity_public_key[1])
    write_to_temp(dest, 0o755 << 16, new_data)

  # Replace the keyid string in BOOT/cmdline.
  if OPTIONS.replace_verity_keyid:
    new_cmdline = ReplaceVerityKeyId(input_tf_zip, output_tf_zip,
      OPTIONS.replace_verity_keyid[1])
    # Writing the new cmdline to tmpdir is redundant as the bootimage
    # gets build in the add_image_to_target_files and rebuild_recovery
    # is not exercised while building the boot image for the A/B
    # path
    write_to_temp("BOOT/cmdline", 0o755 << 16, new_cmdline)

  if rebuild_recovery:
    recovery_img = common.GetBootableImage(
        "recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info)
    boot_img = common.GetBootableImage(
        "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)

    def output_sink(fn, data):
      common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data)

    common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
                             info_dict=misc_info)

  shutil.rmtree(tmpdir)


def ReplaceCerts(data):
  """Given a string of data, replace all occurences of a set
  of X509 certs with a newer set of X509 certs and return
예제 #15
0
def WriteFullOTAPackage(input_zip, output_file):
    target_info = common.BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)

    # We don't know what version it will be installed on top of. We expect the API
    # just won't change very often. Similarly for fstab, it might have changed in
    # the target build.
    target_api_version = target_info["recovery_api_version"]
    script = edify_generator.EdifyGenerator(target_api_version, target_info)

    if target_info.oem_props and not OPTIONS.oem_no_mount:
        target_info.WriteMountOemScript(script)

    metadata = GetPackageMetadata(target_info)

    if not OPTIONS.no_signing:
        staging_file = common.MakeTempFile(suffix='.zip')
    else:
        staging_file = output_file

    output_zip = zipfile.ZipFile(staging_file,
                                 "w",
                                 compression=zipfile.ZIP_DEFLATED)

    device_specific = common.DeviceSpecificParams(
        input_zip=input_zip,
        input_version=target_api_version,
        output_zip=output_zip,
        script=script,
        input_tmp=OPTIONS.input_tmp,
        metadata=metadata,
        info_dict=OPTIONS.info_dict)

    assert HasRecoveryPatch(input_zip, info_dict=OPTIONS.info_dict)

    # Assertions (e.g. downgrade check, device properties check).
    ts = target_info.GetBuildProp("ro.build.date.utc")
    ts_text = target_info.GetBuildProp("ro.build.date")
    script.AssertOlderBuild(ts, ts_text)

    target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
    device_specific.FullOTA_Assertions()

    block_diff_dict = GetBlockDifferences(target_zip=input_zip,
                                          source_zip=None,
                                          target_info=target_info,
                                          source_info=None,
                                          device_specific=device_specific)

    # Two-step package strategy (in chronological order, which is *not*
    # the order in which the generated script has things):
    #
    # if stage is not "2/3" or "3/3":
    #    write recovery image to boot partition
    #    set stage to "2/3"
    #    reboot to boot partition and restart recovery
    # else if stage is "2/3":
    #    write recovery image to recovery partition
    #    set stage to "3/3"
    #    reboot to recovery partition and restart recovery
    # else:
    #    (stage must be "3/3")
    #    set stage to ""
    #    do normal full package installation:
    #       wipe and install system, boot image, etc.
    #       set up system to update recovery partition on first boot
    #    complete script normally
    #    (allow recovery to mark itself finished and reboot)

    #recovery_img = common.GetBootableImage("recovery.img", "recovery.img",
    #                                       OPTIONS.input_tmp, "RECOVERY")
    if OPTIONS.two_step:
        if not target_info.get("multistage_support"):
            assert False, "two-step packages not supported by this build"
        fs = target_info["fstab"]["/misc"]
        assert fs.fs_type.upper() == "EMMC", \
            "two-step packages only supported on devices with EMMC /misc partitions"
        bcb_dev = {"bcb_dev": fs.device}
        common.ZipWriteStr(output_zip, "recovery.img", recovery_img.data)
        script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

        # Stage 2/3: Write recovery image to /recovery (currently running /boot).
        script.Comment("Stage 2/3")
        #script.WriteRawImage("/recovery", "recovery.img")
        script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") == "3/3" then
""" % bcb_dev)

        # Stage 3/3: Make changes.
        script.Comment("Stage 3/3")

    # Dump fingerprints
    script.Print("Target: {}".format(target_info.fingerprint))

    script.AppendExtra(
        "ifelse(is_mounted(\"/system\"), unmount(\"/system\"));")
    device_specific.FullOTA_InstallBegin()

    # All other partitions as well as the data wipe use 10% of the progress, and
    # the update of the system partition takes the remaining progress.
    system_progress = 0.9 - (len(block_diff_dict) - 1) * 0.1
    if OPTIONS.wipe_user_data:
        system_progress -= 0.1
    progress_dict = {partition: 0.1 for partition in block_diff_dict}
    progress_dict["system"] = system_progress

    if target_info.get('use_dynamic_partitions') == "true":
        # Use empty source_info_dict to indicate that all partitions / groups must
        # be re-added.
        dynamic_partitions_diff = common.DynamicPartitionsDifference(
            info_dict=OPTIONS.info_dict,
            block_diffs=block_diff_dict.values(),
            progress_dict=progress_dict)
        dynamic_partitions_diff.WriteScript(script,
                                            output_zip,
                                            write_verify_script=OPTIONS.verify)
    else:
        for block_diff in block_diff_dict.values():
            block_diff.WriteScript(script,
                                   output_zip,
                                   progress=progress_dict.get(
                                       block_diff.partition),
                                   write_verify_script=OPTIONS.verify)

    CheckVintfIfTrebleEnabled(OPTIONS.input_tmp, target_info)

    boot_img = common.GetBootableImage("boot.img", "boot.img",
                                       OPTIONS.input_tmp, "BOOT")
    common.CheckSize(boot_img.data, "boot.img", target_info)
    common.ZipWriteStr(output_zip, "boot.img", boot_img.data)

    script.WriteRawImage("/boot", "boot.img")

    script.ShowProgress(0.1, 10)
    device_specific.FullOTA_InstallEnd()

    if OPTIONS.extra_script is not None:
        script.AppendExtra(OPTIONS.extra_script)

    script.UnmountAll()

    if OPTIONS.wipe_user_data:
        script.ShowProgress(0.1, 10)
        script.FormatPartition("/data")

    if OPTIONS.two_step:
        script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
""" % bcb_dev)
        script.AppendExtra("else\n")

        # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot.
        script.Comment("Stage 1/3")
        _WriteRecoveryImageToBoot(script, output_zip)

        script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

    script.SetProgress(1)
    script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
    metadata.required_cache = script.required_cache

    # We haven't written the metadata entry, which will be done in
    # FinalizeMetadata.
    common.ZipClose(output_zip)

    needed_property_files = (NonAbOtaPropertyFiles(), )
    FinalizeMetadata(metadata, staging_file, output_file,
                     needed_property_files)
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print "target_files appears to already contain images."
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip)
    if "selinux_fc" in OPTIONS.info_dict:
        OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp,
                                                       "BOOT", "RAMDISK",
                                                       "file_contexts")

    common.ZipClose(input_zip)
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED)

    fstab = OPTIONS.info_dict["fstab"]
    if fstab:
        ubi_fs = (fstab["/system"].fs_type == "ubifs")
    else:
        ubi_fs = False

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    banner("boot")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        print "boot.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            boot_image.AddToZip(output_zip)
            # overlay boot image in product out folder
            if outpath:
                open(outpath + '/boot.img', 'w').write(boot_image.data)
                os.chmod(
                    outpath + '/boot.img',
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)

    banner("recovery")
    recovery_image = None
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
    if os.path.exists(prebuilt_path):
        print "recovery.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
    else:
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        if recovery_image:
            recovery_image.AddToZip(output_zip)
            # overlay recovery image in product out folder
            if outpath:
                open(outpath + '/recovery.img', 'w').write(recovery_image.data)
                os.chmod(
                    outpath + '/recovery.img',
                    stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
    if not ubi_fs:
        banner("system")
        AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    #banner("userdata")
    #AddUserdata(output_zip)
    #banner("cache")
    #AddCache(output_zip)

    if outpath:
        zip_dir(OPTIONS.input_tmp, 'META', outpath, 'oem_fota_meta')
        zip_dir(OPTIONS.input_tmp, 'OTA', outpath, 'oem_fota_meta')
        if ubi_fs:
            zip_dir(OPTIONS.input_tmp, 'SYSTEM', outpath, 'oem_fota_meta')
        zf = zipfile.ZipFile(outpath + '/oem_fota_meta.zip', "a",
                             zipfile.zlib.DEFLATED)
        if not ubi_fs:
            common.ZipWrite(zf, outpath + '/system.map', '/IMAGES/system.map')
            common.ZipWrite(zf, OPTIONS.input_tmp + '/SYSTEM/build.prop',
                            '/SYSTEM/build.prop')
            common.ZipWrite(zf,
                            OPTIONS.input_tmp + '/SYSTEM/recovery-from-boot.p',
                            '/SYSTEM/recovery-from-boot.p')
            common.ZipWrite(
                zf, OPTIONS.input_tmp + '/SYSTEM/bin/install-recovery.sh',
                '/SYSTEM/bin/install-recovery.sh')
        common.ZipWrite(zf, OPTIONS.input_tmp + '/RADIO/filesmap',
                        '/RADIO/filesmap')
        zf.close()
    common.ZipClose(output_zip)
예제 #17
0
def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
    source_version = OPTIONS.source_info_dict["recovery_api_version"]
    target_version = OPTIONS.target_info_dict["recovery_api_version"]

    if source_version == 0:
        print(
            "WARNING: generating edify script for a source that "
            "can't install it.")
    script = edify_generator.EdifyGenerator(source_version,
                                            OPTIONS.target_info_dict)

    if OPTIONS.override_prop:
        metadata = {
            "post-timestamp":
            GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict),
        }
    else:
        metadata = {
            "pre-device":
            GetBuildProp("ro.product.device", OPTIONS.source_info_dict),
            "post-timestamp":
            GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict),
        }

    device_specific = common.DeviceSpecificParams(
        source_zip=source_zip,
        source_version=source_version,
        target_zip=target_zip,
        target_version=target_version,
        output_zip=output_zip,
        script=script,
        metadata=metadata,
        info_dict=OPTIONS.info_dict)

    print "Loading target..."
    target_data = LoadSystemFiles(target_zip)
    print "Loading source..."
    source_data = LoadSystemFiles(source_zip)

    verbatim_targets = []
    patch_list = []
    diffs = []
    renames = {}
    largest_source_size = 0

    matching_file_cache = {}
    for fn in source_data.keys():
        sf = source_data[fn]
        assert fn == sf.name
        matching_file_cache["path:" + fn] = sf
        # Only allow eligability for filename/sha matching
        # if there isn't a perfect path match.
        if target_data.get(sf.name) is None:
            matching_file_cache["file:" + fn.split("/")[-1]] = sf
            matching_file_cache["sha:" + sf.sha1] = sf

    for fn in sorted(target_data.keys()):
        tf = target_data[fn]
        assert fn == tf.name
        sf = ClosestFileMatch(tf, matching_file_cache, renames)
        if sf is not None and sf.name != tf.name:
            print "File has moved from " + sf.name + " to " + tf.name
            renames[sf.name] = tf

        if sf is None or fn in OPTIONS.require_verbatim:
            # This file should be included verbatim
            if fn in OPTIONS.prohibit_verbatim:
                raise common.ExternalError("\"%s\" must be sent verbatim" %
                                           (fn, ))
            print "send", fn, "verbatim"
            tf.AddToZip(output_zip)
            verbatim_targets.append((fn, tf.size))
        elif tf.sha1 != sf.sha1:
            # File is different; consider sending as a patch
            diffs.append(common.Difference(tf, sf))
        else:
            # Target file data identical to source (may still be renamed)
            pass


#  common.ComputeDifferences(diffs)
#
#  for diff in diffs:
#    tf, sf, d = diff.GetPatch()
#    if d is None or len(d) > tf.size * OPTIONS.patch_threshold:
#      # patch is almost as big as the file; don't bother patching
#      tf.AddToZip(output_zip)
#      verbatim_targets.append((tf.name, tf.size))
#    else:
#      common.ZipWriteStr(output_zip, "patch/" + sf.name + ".p", d)
#      patch_list.append((sf.name, tf, sf, tf.size, common.sha1(d).hexdigest()))
#      largest_source_size = max(largest_source_size, sf.size)

    if not OPTIONS.override_prop:
        source_fp = GetBuildProp("ro.build.fingerprint",
                                 OPTIONS.source_info_dict)
        target_fp = GetBuildProp("ro.build.fingerprint",
                                 OPTIONS.target_info_dict)
        metadata["pre-build"] = source_fp
        metadata["post-build"] = target_fp

        script.Mount("/system")
        script.AssertSomeFingerprint(source_fp, target_fp)

    source_boot = common.GetBootableImage("/tmp/boot.img", "boot.img",
                                          OPTIONS.source_tmp, "BOOT",
                                          OPTIONS.source_info_dict)
    target_boot = common.GetBootableImage("/tmp/boot.img", "boot.img",
                                          OPTIONS.target_tmp, "BOOT")
    updating_boot = (source_boot.data != target_boot.data)

    #source_recovery = common.GetBootableImage(
    #    "/tmp/recovery.img", "recovery.img", OPTIONS.source_tmp, "RECOVERY",
    #    OPTIONS.source_info_dict)
    #target_recovery = common.GetBootableImage(
    #    "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")
    #updating_recovery = (source_recovery.data != target_recovery.data)
    updating_recovery = False

    # Here's how we divide up the progress bar:
    #  0.1 for verifying the start state (PatchCheck calls)
    #  0.8 for applying patches (ApplyPatch calls)
    #  0.1 for unpacking verbatim files, symlinking, and doing the
    #      device-specific commands.

    AppendAssertions(script, OPTIONS.target_info_dict)
    device_specific.IncrementalOTA_Assertions()

    script.Print("Verifying current system...")

    device_specific.IncrementalOTA_VerifyBegin()

    script.ShowProgress(0.1, 0)
    total_verify_size = float(sum([i[2].size for i in patch_list]) + 1)
    if updating_boot:
        total_verify_size += source_boot.size
    so_far = 0

    for fn, tf, sf, size, patch_sha in patch_list:
        script.PatchCheck("/" + fn, tf.sha1, sf.sha1)
        so_far += sf.size
        script.SetProgress(so_far / total_verify_size)

    if updating_boot:
        d = common.Difference(target_boot, source_boot)
        _, _, d = d.ComputePatch()
        print "boot      target: %d  source: %d  diff: %d" % (
            target_boot.size, source_boot.size, len(d))

        common.ZipWriteStr(output_zip, "patch/boot.img.p", d)

        boot_type, boot_device = common.GetTypeAndDevice(
            "/boot", OPTIONS.info_dict)

        script.PatchCheck(
            "%s:%s:%d:%s:%d:%s" %
            (boot_type, boot_device, source_boot.size, source_boot.sha1,
             target_boot.size, target_boot.sha1))
        so_far += source_boot.size
        script.SetProgress(so_far / total_verify_size)

    if patch_list or updating_recovery or updating_boot:
        script.CacheFreeSpaceCheck(largest_source_size)

    device_specific.IncrementalOTA_VerifyEnd()

    script.Comment("---- start making changes here ----")

    device_specific.IncrementalOTA_InstallBegin()

    if OPTIONS.wipe_user_data:
        script.Print("Erasing user data...")
        script.FormatPartition("/data")

    script.Print("Removing unneeded files...")
    script.DeleteFiles(["/" + i[0] for i in verbatim_targets] + [
        "/" + i for i in sorted(source_data)
        if i not in target_data and i not in renames
    ] + ["/system/recovery.img"])

    script.ShowProgress(0.8, 0)
    total_patch_size = float(sum([i[1].size for i in patch_list]) + 1)
    if updating_boot:
        total_patch_size += target_boot.size
    so_far = 0

    script.Print("Patching system files...")
    deferred_patch_list = []
    for item in patch_list:
        fn, tf, sf, size, _ = item
        if tf.name == "system/build.prop":
            deferred_patch_list.append(item)
            continue
        script.ApplyPatch("/" + fn, "-", tf.size, tf.sha1, sf.sha1,
                          "patch/" + fn + ".p")
        so_far += tf.size
        script.SetProgress(so_far / total_patch_size)

    if updating_boot:
        # Produce the boot image by applying a patch to the current
        # contents of the boot partition, and write it back to the
        # partition.
        script.Print("Patching boot image...")
        script.ApplyPatch(
            "%s:%s:%d:%s:%d:%s" %
            (boot_type, boot_device, source_boot.size, source_boot.sha1,
             target_boot.size, target_boot.sha1), "-", target_boot.size,
            target_boot.sha1, source_boot.sha1, "patch/boot.img.p")
        so_far += target_boot.size
        script.SetProgress(so_far / total_patch_size)
        print "boot image changed; including."
    else:
        print "boot image unchanged; skipping."

    if updating_recovery:
        # Recovery is generated as a patch using both the boot image
        # (which contains the same linux kernel as recovery) and the file
        # /system/etc/recovery-resource.dat (which contains all the images
        # used in the recovery UI) as sources.  This lets us minimize the
        # size of the patch, which must be included in every OTA package.
        #
        # For older builds where recovery-resource.dat is not present, we
        # use only the boot image as the source.

        MakeRecoveryPatch(OPTIONS.target_tmp, output_zip, target_recovery,
                          target_boot)
        script.DeleteFiles([
            "/system/recovery-from-boot.p", "/system/etc/install-recovery.sh"
        ])
        print "recovery image changed; including as patch from boot."
    else:
        print "recovery image unchanged; skipping."

    script.ShowProgress(0.1, 10)

    target_symlinks = CopySystemFiles(target_zip, None)

    target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks])
    temp_script = script.MakeTemporary()
    Item.GetMetadata(target_zip)
    Item.Get("system").SetPermissions(temp_script)

    # Note that this call will mess up the tree of Items, so make sure
    # we're done with it.
    source_symlinks = CopySystemFiles(source_zip, None)
    source_symlinks_d = dict([(i[1], i[0]) for i in source_symlinks])

    # Delete all the symlinks in source that aren't in target.  This
    # needs to happen before verbatim files are unpacked, in case a
    # symlink in the source is replaced by a real file in the target.
    to_delete = []
    for dest, link in source_symlinks:
        if link not in target_symlinks_d:
            to_delete.append(link)
    script.DeleteFiles(to_delete)

    if verbatim_targets:
        script.Print("Unpacking new files...")
        script.UnpackPackageDir("system", "/system")

    #if updating_recovery:
    #  script.Print("Unpacking new recovery...")
    #  script.UnpackPackageDir("recovery", "/system")

    if len(renames) > 0:
        script.Print("Renaming files...")

    for src in renames:
        print "Renaming " + src + " to " + renames[src].name
        script.RenameFile(src, renames[src].name)

    script.Print("Symlinks and permissions...")

    # Create all the symlinks that don't already exist, or point to
    # somewhere different than what we want.  Delete each symlink before
    # creating it, since the 'symlink' command won't overwrite.
    to_create = []
    for dest, link in target_symlinks:
        if link in source_symlinks_d:
            if dest != source_symlinks_d[link]:
                to_create.append((dest, link))
        else:
            to_create.append((dest, link))
    script.DeleteFiles([i[1] for i in to_create])
    script.MakeSymlinks(to_create)

    # Now that the symlinks are created, we can set all the
    # permissions.
    script.AppendScript(temp_script)

    # Do device-specific installation (eg, write radio image).
    device_specific.IncrementalOTA_InstallEnd()

    if OPTIONS.extra_script is not None:
        script.AppendExtra(OPTIONS.extra_script)

    # Patch the build.prop file last, so if something fails but the
    # device can still come up, it appears to be the old build and will
    # get set the OTA package again to retry.
    script.Print("Patching remaining system files...")
    for item in deferred_patch_list:
        fn, tf, sf, size, _ = item
        script.ApplyPatch("/" + fn, "-", tf.size, tf.sha1, sf.sha1,
                          "patch/" + fn + ".p")
    script.SetPermissions("/system/build.prop", 0, 0, 0644, None, None)

    script.AddToZip(target_zip, output_zip)
    WriteMetadata(metadata, output_zip)
def AddImagesToTargetFiles(filename):
    if os.path.isdir(filename):
        OPTIONS.input_tmp = os.path.abspath(filename)
        input_zip = None
    else:
        OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
            print("target_files appears to already contain images.")
            sys.exit(1)

    has_vendor = os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR"))
    has_system_other = os.path.isdir(
        os.path.join(OPTIONS.input_tmp, "SYSTEM_OTHER"))

    if input_zip:
        OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

        common.ZipClose(input_zip)
        output_zip = zipfile.ZipFile(filename,
                                     "a",
                                     compression=zipfile.ZIP_DEFLATED,
                                     allowZip64=True)
    else:
        OPTIONS.info_dict = common.LoadInfoDict(filename, filename)
        output_zip = None
        images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
        if not os.path.isdir(images_dir):
            os.makedirs(images_dir)
        images_dir = None

    has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")

    def banner(s):
        print("\n\n++++ " + s + " ++++\n\n")

    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        banner("boot")
        print("boot.img already exists in IMAGES/, no need to rebuild...")
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        banner("boot")
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            if output_zip:
                boot_image.AddToZip(output_zip)
            else:
                boot_image.WriteToDir(OPTIONS.input_tmp)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                     "recovery.img")
        if os.path.exists(prebuilt_path):
            print(
                "recovery.img already exists in IMAGES/, no need to rebuild..."
            )
            if OPTIONS.rebuild_recovery:
                recovery_image = common.GetBootableImage(
                    "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
                    "RECOVERY")
        else:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
            if recovery_image:
                if output_zip:
                    recovery_image.AddToZip(output_zip)
                else:
                    recovery_image.WriteToDir(OPTIONS.input_tmp)

            banner("recovery (two-step image)")
            # The special recovery.img for two-step package use.
            recovery_two_step_image = common.GetBootableImage(
                "IMAGES/recovery-two-step.img",
                "recovery-two-step.img",
                OPTIONS.input_tmp,
                "RECOVERY",
                two_step_image=True)
            if recovery_two_step_image:
                if output_zip:
                    recovery_two_step_image.AddToZip(output_zip)
                else:
                    recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)

    banner("system")
    system_img_path = AddSystem(output_zip,
                                recovery_img=recovery_image,
                                boot_img=boot_image)
    vendor_img_path = None
    if has_vendor:
        banner("vendor")
        vendor_img_path = AddVendor(output_zip)
    if has_system_other:
        banner("system_other")
        AddSystemOther(output_zip)
    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)
        banner("cache")
        AddCache(output_zip)

    if OPTIONS.info_dict.get("board_bpt_enable") == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    dtbo_img_path = None
    if OPTIONS.info_dict.get("has_dtbo") == "true":
        banner("dtbo")
        dtbo_img_path = AddDtbo(output_zip)

    if OPTIONS.info_dict.get("avb_enable") == "true":
        banner("vbmeta")
        boot_contents = boot_image.WriteToTemp()
        AddVBMeta(output_zip, boot_contents.name, system_img_path,
                  vendor_img_path, dtbo_img_path)

    # For devices using A/B update, copy over images from RADIO/ and/or
    # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
    # images ready under IMAGES/. All images should have '.img' as extension.
    banner("radio")
    ab_partitions = os.path.join(OPTIONS.input_tmp, "META",
                                 "ab_partitions.txt")
    if os.path.exists(ab_partitions):
        with open(ab_partitions, 'r') as f:
            lines = f.readlines()
        # For devices using A/B update, generate care_map for system and vendor
        # partitions (if present), then write this file to target_files package.
        care_map_list = []
        for line in lines:
            if line.strip() == "system" and (
                    "system_verity_block_device" in OPTIONS.info_dict
                    or OPTIONS.info_dict.get("avb_system_hashtree_enable")
                    == "true"):
                assert os.path.exists(system_img_path)
                care_map_list += GetCareMap("system", system_img_path)
            if line.strip() == "vendor" and (
                    "vendor_verity_block_device" in OPTIONS.info_dict
                    or OPTIONS.info_dict.get("avb_vendor_hashtree_enable")
                    == "true"):
                assert os.path.exists(vendor_img_path)
                care_map_list += GetCareMap("vendor", vendor_img_path)

            img_name = line.strip() + ".img"
            prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
            if os.path.exists(prebuilt_path):
                print("%s already exists, no need to overwrite..." %
                      (img_name, ))
                continue

            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            img_vendor_dir = os.path.join(OPTIONS.input_tmp, "VENDOR_IMAGES")
            if os.path.exists(img_radio_path):
                if output_zip:
                    common.ZipWrite(output_zip, img_radio_path,
                                    os.path.join("IMAGES", img_name))
                else:
                    shutil.copy(img_radio_path, prebuilt_path)
            else:
                for root, _, files in os.walk(img_vendor_dir):
                    if img_name in files:
                        if output_zip:
                            common.ZipWrite(output_zip,
                                            os.path.join(root, img_name),
                                            os.path.join("IMAGES", img_name))
                        else:
                            shutil.copy(os.path.join(root, img_name),
                                        prebuilt_path)
                        break

            if output_zip:
                # Zip spec says: All slashes MUST be forward slashes.
                img_path = 'IMAGES/' + img_name
                assert img_path in output_zip.namelist(
                ), "cannot find " + img_name
            else:
                img_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
                assert os.path.exists(img_path), "cannot find " + img_name

        if care_map_list:
            care_map_path = "META/care_map.txt"
            if output_zip and care_map_path not in output_zip.namelist():
                common.ZipWriteStr(output_zip, care_map_path,
                                   '\n'.join(care_map_list))
            else:
                with open(os.path.join(OPTIONS.input_tmp, care_map_path),
                          'w') as fp:
                    fp.write('\n'.join(care_map_list))
                if output_zip:
                    OPTIONS.replace_updated_files_list.append(care_map_path)

    # Radio images that need to be packed into IMAGES/, and product-img.zip.
    pack_radioimages = os.path.join(OPTIONS.input_tmp, "META",
                                    "pack_radioimages.txt")
    if os.path.exists(pack_radioimages):
        with open(pack_radioimages, 'r') as f:
            lines = f.readlines()
        for line in lines:
            img_name = line.strip()
            _, ext = os.path.splitext(img_name)
            if not ext:
                img_name += ".img"
            prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
            if os.path.exists(prebuilt_path):
                print("%s already exists, no need to overwrite..." %
                      (img_name, ))
                continue

            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            assert os.path.exists(img_radio_path), \
                "Failed to find %s at %s" % (img_name, img_radio_path)
            if output_zip:
                common.ZipWrite(output_zip, img_radio_path,
                                os.path.join("IMAGES", img_name))
            else:
                shutil.copy(img_radio_path, prebuilt_path)

    if output_zip:
        common.ZipClose(output_zip)
        if OPTIONS.replace_updated_files_list:
            ReplaceUpdatedFiles(output_zip.filename,
                                OPTIONS.replace_updated_files_list)
예제 #19
0
=======
          if image == "recovery-two-step.img":
>>>>>>> android-7.1.2_r2
            continue
          common.ZipWrite(
              output_zip, os.path.join(images_path, image), image)
        done = True

    if not done:
      # We have an old target-files that doesn't already contain the
      # images, so build them.
      import add_img_to_target_files

      OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

      boot_image = common.GetBootableImage(
          "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
      if boot_image:
        boot_image.AddToZip(output_zip)

      if OPTIONS.info_dict.get("no_recovery") != "true":
        recovery_image = common.GetBootableImage(
            "recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
        if recovery_image:
          recovery_image.AddToZip(output_zip)

      def banner(s):
        print("\n\n++++ " + s + " ++++\n\n")

      if not bootable_only:
        banner("AddSystem")
        add_img_to_target_files.AddSystem(output_zip, prefix="")
예제 #20
0
def AddImagesToTargetFiles(filename):
    """Creates and adds images (boot/recovery/system/...) to a target_files.zip.

  It works with either a zip file (zip mode), or a directory that contains the
  files to be packed into a target_files.zip (dir mode). The latter is used when
  being called from build/make/core/Makefile.

  The images will be created under IMAGES/ in the input target_files.zip.

  Args:
    filename: the target_files.zip, or the zip root directory.
  """
    if os.path.isdir(filename):
        OPTIONS.input_tmp = os.path.abspath(filename)
    else:
        OPTIONS.input_tmp = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
            print("target_files appears to already contain images.")
            sys.exit(1)

    OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp,
                                            OPTIONS.input_tmp)

    has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"

    # {vendor,product}.img is unlike system.img or system_other.img. Because it
    # could be built from source, or dropped into target_files.zip as a prebuilt
    # blob. We consider either of them as {vendor,product}.img being available,
    # which could be used when generating vbmeta.img for AVB.
    has_vendor = (
        (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR"))
         or os.path.exists(
             os.path.join(OPTIONS.input_tmp, "IMAGES", "vendor.img")))
        and OPTIONS.info_dict.get("vendor_prebuilt_installed") != "true")
    has_product = (os.path.isdir(os.path.join(
        OPTIONS.input_tmp, "PRODUCT")) or os.path.exists(
            os.path.join(OPTIONS.input_tmp, "IMAGES", "product.img")))
    has_system_other = os.path.isdir(
        os.path.join(OPTIONS.input_tmp, "SYSTEM_OTHER"))

    # Set up the output destination. It writes to the given directory for dir
    # mode; otherwise appends to the given ZIP.
    if os.path.isdir(filename):
        output_zip = None
    else:
        output_zip = zipfile.ZipFile(filename,
                                     "a",
                                     compression=zipfile.ZIP_DEFLATED,
                                     allowZip64=True)

    # Always make input_tmp/IMAGES available, since we may stage boot / recovery
    # images there even under zip mode. The directory will be cleaned up as part
    # of OPTIONS.input_tmp.
    images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
    if not os.path.isdir(images_dir):
        os.makedirs(images_dir)

    # A map between partition names and their paths, which could be used when
    # generating AVB vbmeta image.
    partitions = dict()

    def banner(s):
        print("\n\n++++ " + s + " ++++\n\n")

    banner("boot")
    # common.GetBootableImage() returns the image directly if present.
    boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                         OPTIONS.input_tmp, "BOOT")
    # boot.img may be unavailable in some targets (e.g. aosp_arm64).
    if boot_image:
        partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                          "boot.img")
        if not os.path.exists(partitions['boot']):
            boot_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        assert recovery_image, "Failed to create recovery.img."
        partitions['recovery'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "recovery.img")
        if not os.path.exists(partitions['recovery']):
            recovery_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                recovery_image.AddToZip(output_zip)

            banner("recovery (two-step image)")
            # The special recovery.img for two-step package use.
            recovery_two_step_image = common.GetBootableImage(
                "IMAGES/recovery-two-step.img",
                "recovery-two-step.img",
                OPTIONS.input_tmp,
                "RECOVERY",
                two_step_image=True)
            assert recovery_two_step_image, "Failed to create recovery-two-step.img."
            recovery_two_step_image_path = os.path.join(
                OPTIONS.input_tmp, "IMAGES", "recovery-two-step.img")
            if not os.path.exists(recovery_two_step_image_path):
                recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
                if output_zip:
                    recovery_two_step_image.AddToZip(output_zip)

    banner("system")
    partitions['system'] = AddSystem(output_zip,
                                     recovery_img=recovery_image,
                                     boot_img=boot_image)

    if has_vendor:
        banner("vendor")
        partitions['vendor'] = AddVendor(output_zip)

    if has_product:
        banner("product")
        partitions['product'] = AddProduct(output_zip)

    if has_system_other:
        banner("system_other")
        AddSystemOther(output_zip)

    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)
        banner("cache")
        AddCache(output_zip)

    if OPTIONS.info_dict.get("board_bpt_enable") == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    if OPTIONS.info_dict.get("has_dtbo") == "true":
        banner("dtbo")
        partitions['dtbo'] = AddDtbo(output_zip)

    if OPTIONS.info_dict.get("avb_enable") == "true":
        banner("vbmeta")
        AddVBMeta(output_zip, partitions)

    banner("radio")
    ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                     "ab_partitions.txt")
    if os.path.exists(ab_partitions_txt):
        with open(ab_partitions_txt, 'r') as f:
            ab_partitions = f.readlines()

        # For devices using A/B update, copy over images from RADIO/ and/or
        # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
        # images ready under IMAGES/. All images should have '.img' as extension.
        AddRadioImagesForAbOta(output_zip, ab_partitions)

        # Generate care_map.txt for system and vendor partitions (if present), then
        # write this file to target_files package.
        AddCareMapTxtForAbOta(output_zip, ab_partitions, partitions)

    # Radio images that need to be packed into IMAGES/, and product-img.zip.
    pack_radioimages_txt = os.path.join(OPTIONS.input_tmp, "META",
                                        "pack_radioimages.txt")
    if os.path.exists(pack_radioimages_txt):
        with open(pack_radioimages_txt, 'r') as f:
            AddPackRadioImages(output_zip, f.readlines())

    if output_zip:
        common.ZipClose(output_zip)
        if OPTIONS.replace_updated_files_list:
            ReplaceUpdatedFiles(output_zip.filename,
                                OPTIONS.replace_updated_files_list)
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print "target_files appears to already contain images."
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

    common.ZipClose(input_zip)
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED,
                                 allowZip64=True)

    has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")
    system_root_image = (OPTIONS.info_dict.get("system_root_image",
                                               None) == "true")
    board_bvb_enable = (OPTIONS.info_dict.get("board_bvb_enable",
                                              None) == "true")

    # Brillo Verified Boot is incompatible with certain
    # configurations. Explicitly check for these.
    if board_bvb_enable:
        assert not has_recovery, "has_recovery incompatible with bvb"
        assert not system_root_image, "system_root_image incompatible with bvb"
        assert not OPTIONS.rebuild_recovery, "rebuild_recovery incompatible with bvb"
        assert not has_vendor, "VENDOR images currently incompatible with bvb"

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        banner("boot")
        print "boot.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        if board_bvb_enable:
            # With Brillo Verified Boot, we need to build system.img before
            # boot.img since the latter includes the dm-verity root hash and
            # salt for the former.
            pass
        else:
            banner("boot")
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
            if boot_image:
                boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                     "recovery.img")
        if os.path.exists(prebuilt_path):
            print "recovery.img already exists in IMAGES/, no need to rebuild..."
            if OPTIONS.rebuild_recovery:
                recovery_image = common.GetBootableImage(
                    "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
                    "RECOVERY")
        else:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
            if recovery_image:
                recovery_image.AddToZip(output_zip)

    banner("system")
    system_img_path = AddSystem(output_zip,
                                recovery_img=recovery_image,
                                boot_img=boot_image)
    if OPTIONS.info_dict.get("board_bvb_enable", None) == "true":
        # If we're using Brillo Verified Boot, we can now build boot.img
        # given that we have system.img.
        banner("boot")
        boot_image = common.GetBootableImage("IMAGES/boot.img",
                                             "boot.img",
                                             OPTIONS.input_tmp,
                                             "BOOT",
                                             system_img_path=system_img_path)
        if boot_image:
            boot_image.AddToZip(output_zip)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    banner("userdata")
    AddUserdata(output_zip)
    banner("cache")
    AddCache(output_zip)
    if OPTIONS.info_dict.get("board_bpt_enable", None) == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    # For devices using A/B update, copy over images from RADIO/ and/or
    # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
    # images ready under IMAGES/. All images should have '.img' as extension.
    banner("radio")
    ab_partitions = os.path.join(OPTIONS.input_tmp, "META",
                                 "ab_partitions.txt")
    if os.path.exists(ab_partitions):
        with open(ab_partitions, 'r') as f:
            lines = f.readlines()
        for line in lines:
            img_name = line.strip() + ".img"
            prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
            if os.path.exists(prebuilt_path):
                print "%s already exists, no need to overwrite..." % (
                    img_name, )
                continue

            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            img_vendor_dir = os.path.join(OPTIONS.input_tmp, "VENDOR_IMAGES")
            if os.path.exists(img_radio_path):
                common.ZipWrite(output_zip, img_radio_path,
                                os.path.join("IMAGES", img_name))
            else:
                for root, _, files in os.walk(img_vendor_dir):
                    if img_name in files:
                        common.ZipWrite(output_zip,
                                        os.path.join(root, img_name),
                                        os.path.join("IMAGES", img_name))
                        break

            # Zip spec says: All slashes MUST be forward slashes.
            img_path = 'IMAGES/' + img_name
            assert img_path in output_zip.namelist(), "cannot find " + img_name

    common.ZipClose(output_zip)
예제 #22
0
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print("target_files appears to already contain images.")
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    try:
        input_zip.getinfo("OEM/")
        has_oem = True
    except KeyError:
        has_oem = False

    has_system_other = "SYSTEM_OTHER/" in input_zip.namelist()

    OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

    common.ZipClose(input_zip)
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED)

    has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")

    def banner(s):
        print("\n\n++++ " + s + " ++++\n\n")

    banner("boot")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        print("boot.img already exists in IMAGES/, no need to rebuild...")
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                     "recovery.img")
        if os.path.exists(prebuilt_path):
            print(
                "recovery.img already exists in IMAGES/, no need to rebuild..."
            )
            if OPTIONS.rebuild_recovery:
                recovery_image = common.GetBootableImage(
                    "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
                    "RECOVERY")
        else:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
            if recovery_image:
                recovery_image.AddToZip(output_zip)

    banner("system")
    system_imgname = AddSystem(output_zip,
                               recovery_img=recovery_image,
                               boot_img=boot_image)
    vendor_imgname = None
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)
        banner("cache")
        AddCache(output_zip)
    if OPTIONS.info_dict.get("board_bpt_enable", None) == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    # For devices using A/B update, copy over images from RADIO/ and/or
    # VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
    # images ready under IMAGES/. All images should have '.img' as extension.
    banner("radio")
    ab_partitions = os.path.join(OPTIONS.input_tmp, "META",
                                 "ab_partitions.txt")
    if os.path.exists(ab_partitions):
        with open(ab_partitions, 'r') as f:
            lines = f.readlines()
        # For devices using A/B update, generate care_map for system and vendor
        # partitions (if present), then write this file to target_files package.
        care_map_list = []
        for line in lines:
            if line.strip() == "system" and OPTIONS.info_dict.get(
                    "system_verity_block_device", None) is not None:
                assert os.path.exists(system_imgname)
                care_map_list += GetCareMap("system", system_imgname)
            if line.strip() == "vendor" and OPTIONS.info_dict.get(
                    "vendor_verity_block_device", None) is not None:
                assert os.path.exists(vendor_imgname)
                care_map_list += GetCareMap("vendor", vendor_imgname)

            img_name = line.strip() + ".img"
            img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
            if os.path.exists(img_radio_path):
                common.ZipWrite(output_zip, img_radio_path,
                                os.path.join("IMAGES", img_name))

            # Zip spec says: All slashes MUST be forward slashes.
            img_path = 'IMAGES/' + img_name
            assert img_path in output_zip.namelist(), "cannot find " + img_name

        if care_map_list:
            file_path = "META/care_map.txt"
            common.ZipWriteStr(output_zip, file_path, '\n'.join(care_map_list))

    common.ZipClose(output_zip)
예제 #23
0
def AddImagesToTargetFiles(filename):
  OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

  if not OPTIONS.add_missing:
    for n in input_zip.namelist():
      if n.startswith("IMAGES/"):
        print "target_files appears to already contain images."
        sys.exit(1)

  try:
    input_zip.getinfo("VENDOR/")
    has_vendor = True
  except KeyError:
    has_vendor = False

  OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

  common.ZipClose(input_zip)
  output_zip = zipfile.ZipFile(filename, "a",
                               compression=zipfile.ZIP_DEFLATED)

  has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")

  def banner(s):
    print "\n\n++++ " + s + " ++++\n\n"

  banner("boot")
  prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
  boot_image = None
  if os.path.exists(prebuilt_path):
    print "boot.img already exists in IMAGES/, no need to rebuild..."
    if OPTIONS.rebuild_recovery:
      boot_image = common.GetBootableImage(
          "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
  else:
    boot_image = common.GetBootableImage(
        "IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
    if boot_image:
      boot_image.AddToZip(output_zip)

  recovery_image = None
  if has_recovery:
    banner("recovery")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
    if os.path.exists(prebuilt_path):
      print "recovery.img already exists in IMAGES/, no need to rebuild..."
      if OPTIONS.rebuild_recovery:
        recovery_image = common.GetBootableImage(
            "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
            "RECOVERY")
    else:
      recovery_image = common.GetBootableImage(
          "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
      if recovery_image:
        recovery_image.AddToZip(output_zip)

  banner("system")
  AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
  if has_vendor:
    banner("vendor")
    AddVendor(output_zip)
  banner("userdata")
  AddUserdata(output_zip)
  banner("cache")
  AddCache(output_zip)

  # For devices using A/B update, copy over images from RADIO/ to IMAGES/ and
  # make sure we have all the needed images ready under IMAGES/.
  ab_partitions = os.path.join(OPTIONS.input_tmp, "META", "ab_partitions.txt")
  if os.path.exists(ab_partitions):
    with open(ab_partitions, 'r') as f:
      lines = f.readlines()
    for line in lines:
      img_name = line.strip() + ".img"
      img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
      if os.path.exists(img_radio_path):
        common.ZipWrite(output_zip, img_radio_path,
                        os.path.join("IMAGES", img_name))

      # Zip spec says: All slashes MUST be forward slashes.
      img_path = 'IMAGES/' + img_name
      assert img_path in output_zip.namelist(), "cannot find " + img_name

  common.ZipClose(output_zip)
예제 #24
0
def AddImagesToTargetFiles(filename):
    """Creates and adds images (boot/recovery/system/...) to a target_files.zip.

  It works with either a zip file (zip mode), or a directory that contains the
  files to be packed into a target_files.zip (dir mode). The latter is used when
  being called from build/make/core/Makefile.

  The images will be created under IMAGES/ in the input target_files.zip.

  Args:
    filename: the target_files.zip, or the zip root directory.
  """
    if os.path.isdir(filename):
        OPTIONS.input_tmp = os.path.abspath(filename)
    else:
        OPTIONS.input_tmp = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
            logger.warning("target_files appears to already contain images.")
            sys.exit(1)

    OPTIONS.info_dict = common.LoadInfoDict(OPTIONS.input_tmp, repacking=True)

    has_recovery = OPTIONS.info_dict.get("no_recovery") != "true"

    # {vendor,odm,product,product_services}.img are unlike system.img or
    # system_other.img. Because it could be built from source, or dropped into
    # target_files.zip as a prebuilt blob. We consider either of them as
    # {vendor,product,product_services}.img being available, which could be
    # used when generating vbmeta.img for AVB.
    has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR"))
                  or os.path.exists(
                      os.path.join(OPTIONS.input_tmp, "IMAGES", "vendor.img")))
    has_odm = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "ODM"))
               or os.path.exists(
                   os.path.join(OPTIONS.input_tmp, "IMAGES", "odm.img")))
    has_product = (os.path.isdir(os.path.join(
        OPTIONS.input_tmp, "PRODUCT")) or os.path.exists(
            os.path.join(OPTIONS.input_tmp, "IMAGES", "product.img")))
    has_product_services = (os.path.isdir(
        os.path.join(OPTIONS.input_tmp, "PRODUCT_SERVICES")) or os.path.exists(
            os.path.join(OPTIONS.input_tmp, "IMAGES", "product_services.img")))
    has_system = os.path.isdir(os.path.join(OPTIONS.input_tmp, "SYSTEM"))
    has_system_other = os.path.isdir(
        os.path.join(OPTIONS.input_tmp, "SYSTEM_OTHER"))

    # Set up the output destination. It writes to the given directory for dir
    # mode; otherwise appends to the given ZIP.
    if os.path.isdir(filename):
        output_zip = None
    else:
        output_zip = zipfile.ZipFile(filename,
                                     "a",
                                     compression=zipfile.ZIP_DEFLATED,
                                     allowZip64=True)

    # Always make input_tmp/IMAGES available, since we may stage boot / recovery
    # images there even under zip mode. The directory will be cleaned up as part
    # of OPTIONS.input_tmp.
    images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
    if not os.path.isdir(images_dir):
        os.makedirs(images_dir)

    # A map between partition names and their paths, which could be used when
    # generating AVB vbmeta image.
    partitions = dict()

    def banner(s):
        logger.info("\n\n++++ " + s + " ++++\n\n")

    banner("boot")
    # common.GetBootableImage() returns the image directly if present.
    boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                         OPTIONS.input_tmp, "BOOT")
    # boot.img may be unavailable in some targets (e.g. aosp_arm64).
    if boot_image:
        partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                          "boot.img")
        if not os.path.exists(partitions['boot']):
            boot_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        assert recovery_image, "Failed to create recovery.img."
        partitions['recovery'] = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                              "recovery.img")
        if not os.path.exists(partitions['recovery']):
            recovery_image.WriteToDir(OPTIONS.input_tmp)
            if output_zip:
                recovery_image.AddToZip(output_zip)

            banner("recovery (two-step image)")
            # The special recovery.img for two-step package use.
            recovery_two_step_image = common.GetBootableImage(
                "IMAGES/recovery-two-step.img",
                "recovery-two-step.img",
                OPTIONS.input_tmp,
                "RECOVERY",
                two_step_image=True)
            assert recovery_two_step_image, "Failed to create recovery-two-step.img."
            recovery_two_step_image_path = os.path.join(
                OPTIONS.input_tmp, "IMAGES", "recovery-two-step.img")
            if not os.path.exists(recovery_two_step_image_path):
                recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
                if output_zip:
                    recovery_two_step_image.AddToZip(output_zip)

    if has_system:
        banner("system")
        partitions['system'] = AddSystem(output_zip,
                                         recovery_img=recovery_image,
                                         boot_img=boot_image)

    if has_vendor:
        banner("vendor")
        partitions['vendor'] = AddVendor(output_zip)

    if has_product:
        banner("product")
        partitions['product'] = AddProduct(output_zip)

    if has_product_services:
        banner("product_services")
        partitions['product_services'] = AddProductServices(output_zip)

    if has_odm:
        banner("odm")
        partitions['odm'] = AddOdm(output_zip)

    if has_system_other:
        banner("system_other")
        AddSystemOther(output_zip)

    if not OPTIONS.is_signing:
        banner("userdata")
        AddUserdata(output_zip)
        banner("cache")
        AddCache(output_zip)

    if OPTIONS.info_dict.get("board_bpt_enable") == "true":
        banner("partition-table")
        AddPartitionTable(output_zip)

    if OPTIONS.info_dict.get("has_dtbo") == "true":
        banner("dtbo")
        partitions['dtbo'] = AddDtbo(output_zip)

    if OPTIONS.info_dict.get("avb_enable") == "true":
        # vbmeta_partitions includes the partitions that should be included into
        # top-level vbmeta.img, which are the ones that are not included in any
        # chained VBMeta image plus the chained VBMeta images themselves.
        vbmeta_partitions = common.AVB_PARTITIONS[:]

        vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip()
        if vbmeta_system:
            banner("vbmeta_system")
            partitions["vbmeta_system"] = AddVBMeta(output_zip, partitions,
                                                    "vbmeta_system",
                                                    vbmeta_system.split())
            vbmeta_partitions = [
                item for item in vbmeta_partitions
                if item not in vbmeta_system.split()
            ]
            vbmeta_partitions.append("vbmeta_system")

        vbmeta_vendor = OPTIONS.info_dict.get("avb_vbmeta_vendor", "").strip()
        if vbmeta_vendor:
            banner("vbmeta_vendor")
            partitions["vbmeta_vendor"] = AddVBMeta(output_zip, partitions,
                                                    "vbmeta_vendor",
                                                    vbmeta_vendor.split())
            vbmeta_partitions = [
                item for item in vbmeta_partitions
                if item not in vbmeta_vendor.split()
            ]
            vbmeta_partitions.append("vbmeta_vendor")

        banner("vbmeta")
        AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)

    if OPTIONS.info_dict.get("build_super_partition") == "true":
        banner("super_empty")
        AddSuperEmpty(output_zip)

        if OPTIONS.info_dict.get(
                "build_retrofit_dynamic_partitions_ota_package") == "true":
            banner("super split images")
            AddSuperSplit(output_zip)

    banner("radio")
    ab_partitions_txt = os.path.join(OPTIONS.input_tmp, "META",
                                     "ab_partitions.txt")
    if os.path.exists(ab_partitions_txt):
        with open(ab_partitions_txt, 'r') as f:
            ab_partitions = f.readlines()

        # For devices using A/B update, make sure we have all the needed images
        # ready under IMAGES/ or RADIO/.
        CheckAbOtaImages(output_zip, ab_partitions)

        # Generate care_map.pb for ab_partitions, then write this file to
        # target_files package.
        AddCareMapForAbOta(output_zip, ab_partitions, partitions)

    # Radio images that need to be packed into IMAGES/, and product-img.zip.
    pack_radioimages_txt = os.path.join(OPTIONS.input_tmp, "META",
                                        "pack_radioimages.txt")
    if os.path.exists(pack_radioimages_txt):
        with open(pack_radioimages_txt, 'r') as f:
            AddPackRadioImages(output_zip, f.readlines())

    if output_zip:
        common.ZipClose(output_zip)
        if OPTIONS.replace_updated_files_list:
            ReplaceUpdatedFiles(output_zip.filename,
                                OPTIONS.replace_updated_files_list)
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print "target_files appears to already contain images."
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    try:
        input_zip.getinfo("CUSTOM/")
        has_custom = True
    except KeyError:
        has_custom = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip)
    if "selinux_fc" in OPTIONS.info_dict:
        OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp,
                                                       "BOOT", "RAMDISK",
                                                       "file_contexts")

    input_zip.close()
    #yutianliang add for VFOZBENQ-91 add :allowZip64=True
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED,
                                 allowZip64=True)

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    banner("boot")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        print "boot.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            boot_image.AddToZip(output_zip)

    banner("recovery")
    recovery_image = None
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
    if os.path.exists(prebuilt_path):
        print "recovery.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
    else:
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        if recovery_image:
            recovery_image.AddToZip(output_zip)

    if "mtk_header_support" in OPTIONS.info_dict:
        banner("recovery_bthdr")
        recovery_bthdr_image = common.GetBootableImage(
            "IMAGES/recovery_bthdr.img", "recovery_bthdr.img",
            OPTIONS.input_tmp, "RECOVERY")
        if recovery_bthdr_image:
            recovery_bthdr_image.AddToZip(output_zip)

    banner("system")
    AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    if has_custom:
        banner("custom")
        AddCustom(output_zip)
    banner("userdata")
    AddUserdata(output_zip)
    banner("cache")
    AddCache(output_zip)

    output_zip.close()
예제 #26
0
def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
  target_info = common.BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
  source_info = common.BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)

  target_api_version = target_info["recovery_api_version"]
  source_api_version = source_info["recovery_api_version"]
  if source_api_version == 0:
    logger.warning(
        "Generating edify script for a source that can't install it.")

  script = edify_generator.EdifyGenerator(
      source_api_version, target_info, fstab=source_info["fstab"])

  if target_info.oem_props or source_info.oem_props:
    if not OPTIONS.oem_no_mount:
      source_info.WriteMountOemScript(script)

  metadata = GetPackageMetadata(target_info, source_info)

  if not OPTIONS.no_signing:
    staging_file = common.MakeTempFile(suffix='.zip')
  else:
    staging_file = output_file

  output_zip = zipfile.ZipFile(
      staging_file, "w", compression=zipfile.ZIP_DEFLATED)

  device_specific = common.DeviceSpecificParams(
      source_zip=source_zip,
      source_version=source_api_version,
      source_tmp=OPTIONS.source_tmp,
      target_zip=target_zip,
      target_version=target_api_version,
      target_tmp=OPTIONS.target_tmp,
      output_zip=output_zip,
      script=script,
      metadata=metadata,
      info_dict=source_info)

  source_boot = common.GetBootableImage(
      "/tmp/boot.img", "boot.img", OPTIONS.source_tmp, "BOOT", source_info)
  target_boot = common.GetBootableImage(
      "/tmp/boot.img", "boot.img", OPTIONS.target_tmp, "BOOT", target_info)
  updating_boot = (not OPTIONS.two_step and
                   (source_boot.data != target_boot.data))

  target_recovery = common.GetBootableImage(
      "/tmp/recovery.img", "recovery.img", OPTIONS.target_tmp, "RECOVERY")

  block_diff_dict = GetBlockDifferences(target_zip=target_zip,
                                        source_zip=source_zip,
                                        target_info=target_info,
                                        source_info=source_info,
                                        device_specific=device_specific)

  CheckVintfIfTrebleEnabled(OPTIONS.target_tmp, target_info)

  # Assertions (e.g. device properties check).
  target_info.WriteDeviceAssertions(script, OPTIONS.oem_no_mount)
  device_specific.IncrementalOTA_Assertions()

  # Two-step incremental package strategy (in chronological order,
  # which is *not* the order in which the generated script has
  # things):
  #
  # if stage is not "2/3" or "3/3":
  #    do verification on current system
  #    write recovery image to boot partition
  #    set stage to "2/3"
  #    reboot to boot partition and restart recovery
  # else if stage is "2/3":
  #    write recovery image to recovery partition
  #    set stage to "3/3"
  #    reboot to recovery partition and restart recovery
  # else:
  #    (stage must be "3/3")
  #    perform update:
  #       patch system files, etc.
  #       force full install of new boot image
  #       set up system to update recovery partition on first boot
  #    complete script normally
  #    (allow recovery to mark itself finished and reboot)

  if OPTIONS.two_step:
    if not source_info.get("multistage_support"):
      assert False, "two-step packages not supported by this build"
    fs = source_info["fstab"]["/misc"]
    assert fs.fs_type.upper() == "EMMC", \
        "two-step packages only supported on devices with EMMC /misc partitions"
    bcb_dev = {"bcb_dev": fs.device}
    common.ZipWriteStr(output_zip, "recovery.img", target_recovery.data)
    script.AppendExtra("""
if get_stage("%(bcb_dev)s") == "2/3" then
""" % bcb_dev)

    # Stage 2/3: Write recovery image to /recovery (currently running /boot).
    script.Comment("Stage 2/3")
    script.AppendExtra("sleep(20);\n")
    script.WriteRawImage("/recovery", "recovery.img")
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "3/3");
reboot_now("%(bcb_dev)s", "recovery");
else if get_stage("%(bcb_dev)s") != "3/3" then
""" % bcb_dev)

    # Stage 1/3: (a) Verify the current system.
    script.Comment("Stage 1/3")

  # Dump fingerprints
  script.Print("Source: {}".format(source_info.fingerprint))
  script.Print("Target: {}".format(target_info.fingerprint))

  script.Print("Verifying current system...")

  device_specific.IncrementalOTA_VerifyBegin()

  WriteFingerprintAssertion(script, target_info, source_info)

  # Check the required cache size (i.e. stashed blocks).
  required_cache_sizes = [diff.required_cache for diff in
                          block_diff_dict.values()]
  if updating_boot:
    boot_type, boot_device_expr = common.GetTypeAndDeviceExpr("/boot",
                                                              source_info)
    d = common.Difference(target_boot, source_boot)
    _, _, d = d.ComputePatch()
    if d is None:
      include_full_boot = True
      common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
    else:
      include_full_boot = False

      logger.info(
          "boot      target: %d  source: %d  diff: %d", target_boot.size,
          source_boot.size, len(d))

      common.ZipWriteStr(output_zip, "boot.img.p", d)

      target_expr = 'concat("{}:",{},":{}:{}")'.format(
          boot_type, boot_device_expr, target_boot.size, target_boot.sha1)
      source_expr = 'concat("{}:",{},":{}:{}")'.format(
          boot_type, boot_device_expr, source_boot.size, source_boot.sha1)
      script.PatchPartitionExprCheck(target_expr, source_expr)

      required_cache_sizes.append(target_boot.size)

  if required_cache_sizes:
    script.CacheFreeSpaceCheck(max(required_cache_sizes))

  # Verify the existing partitions.
  for diff in block_diff_dict.values():
    diff.WriteVerifyScript(script, touched_blocks_only=True)

  device_specific.IncrementalOTA_VerifyEnd()

  if OPTIONS.two_step:
    # Stage 1/3: (b) Write recovery image to /boot.
    _WriteRecoveryImageToBoot(script, output_zip)

    script.AppendExtra("""
set_stage("%(bcb_dev)s", "2/3");
reboot_now("%(bcb_dev)s", "");
else
""" % bcb_dev)

    # Stage 3/3: Make changes.
    script.Comment("Stage 3/3")

  script.Comment("---- start making changes here ----")

  device_specific.IncrementalOTA_InstallBegin()

  progress_dict = {partition: 0.1 for partition in block_diff_dict}
  progress_dict["system"] = 1 - len(block_diff_dict) * 0.1

  if OPTIONS.source_info_dict.get("use_dynamic_partitions") == "true":
    if OPTIONS.target_info_dict.get("use_dynamic_partitions") != "true":
      raise RuntimeError(
          "can't generate incremental that disables dynamic partitions")
    dynamic_partitions_diff = common.DynamicPartitionsDifference(
        info_dict=OPTIONS.target_info_dict,
        source_info_dict=OPTIONS.source_info_dict,
        block_diffs=block_diff_dict.values(),
        progress_dict=progress_dict)
    dynamic_partitions_diff.WriteScript(
        script, output_zip, write_verify_script=OPTIONS.verify)
  else:
    for block_diff in block_diff_dict.values():
      block_diff.WriteScript(script, output_zip,
                             progress=progress_dict.get(block_diff.partition),
                             write_verify_script=OPTIONS.verify)

  if OPTIONS.two_step:
    common.ZipWriteStr(output_zip, "boot.img", target_boot.data)
    script.WriteRawImage("/boot", "boot.img")
    logger.info("writing full boot image (forced by two-step mode)")

  if not OPTIONS.two_step:
    if updating_boot:
      if include_full_boot:
        logger.info("boot image changed; including full.")
        script.Print("Installing boot image...")
        script.WriteRawImage("/boot", "boot.img")
      else:
        # Produce the boot image by applying a patch to the current
        # contents of the boot partition, and write it back to the
        # partition.
        logger.info("boot image changed; including patch.")
        script.Print("Patching boot image...")
        script.ShowProgress(0.1, 10)
        target_expr = 'concat("{}:",{},":{}:{}")'.format(
            boot_type, boot_device_expr, target_boot.size, target_boot.sha1)
        source_expr = 'concat("{}:",{},":{}:{}")'.format(
            boot_type, boot_device_expr, source_boot.size, source_boot.sha1)
        script.PatchPartitionExpr(target_expr, source_expr, '"boot.img.p"')
    else:
      logger.info("boot image unchanged; skipping.")

  # Do device-specific installation (eg, write radio image).
  device_specific.IncrementalOTA_InstallEnd()

  if OPTIONS.extra_script is not None:
    script.AppendExtra(OPTIONS.extra_script)

  if OPTIONS.wipe_user_data:
    script.Print("Erasing user data...")
    script.FormatPartition("/data")

  if OPTIONS.two_step:
    script.AppendExtra("""
set_stage("%(bcb_dev)s", "");
endif;
endif;
""" % bcb_dev)

  script.SetProgress(1)
  # For downgrade OTAs, we prefer to use the update-binary in the source
  # build that is actually newer than the one in the target build.
  if OPTIONS.downgrade:
    script.AddToZip(source_zip, output_zip, input_path=OPTIONS.updater_binary)
  else:
    script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
  metadata.required_cache = script.required_cache

  # We haven't written the metadata entry yet, which will be handled in
  # FinalizeMetadata().
  common.ZipClose(output_zip)

  # Sign the generated zip package unless no_signing is specified.
  needed_property_files = (
      NonAbOtaPropertyFiles(),
  )
  FinalizeMetadata(metadata, staging_file, output_file, needed_property_files)
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print "target_files appears to already contain images."
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)

    common.ZipClose(input_zip)
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED)

    has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    banner("boot")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        print "boot.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            boot_image.AddToZip(output_zip)

    recovery_image = None
    if has_recovery:
        banner("recovery")
        prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES",
                                     "recovery.img")
        if os.path.exists(prebuilt_path):
            print "recovery.img already exists in IMAGES/, no need to rebuild..."
            if OPTIONS.rebuild_recovery:
                recovery_image = common.GetBootableImage(
                    "IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp,
                    "RECOVERY")
        else:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
            if recovery_image:
                recovery_image.AddToZip(output_zip)

    banner("system")
    AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    banner("userdata")
    AddUserdata(output_zip)
    banner("cache")
    AddCache(output_zip)

    common.ZipClose(output_zip)
예제 #28
0
def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info,
                       apk_key_map, key_passwords, platform_api_level,
                       codename_to_api_level_map):

  maxsize = max([len(os.path.basename(i.filename))
                 for i in input_tf_zip.infolist()
                 if i.filename.endswith('.apk')])
  rebuild_recovery = False
  system_root_image = misc_info.get("system_root_image") == "true"

  # tmpdir will only be used to regenerate the recovery-from-boot patch.
  tmpdir = tempfile.mkdtemp()
  def write_to_temp(fn, attr, data):
    fn = os.path.join(tmpdir, fn)
    if fn.endswith("/"):
      fn = os.path.join(tmpdir, fn)
      os.mkdir(fn)
    else:
      d = os.path.dirname(fn)
      if d and not os.path.exists(d):
        os.makedirs(d)

      if attr >> 16 == 0xa1ff:
        os.symlink(data, fn)
      else:
        with open(fn, "wb") as f:
          f.write(data)

  for info in input_tf_zip.infolist():
    if info.filename.startswith("IMAGES/"):
      continue

    data = input_tf_zip.read(info.filename)
    out_info = copy.copy(info)

    # Sign APKs.
    if info.filename.endswith(".apk"):
      name = os.path.basename(info.filename)
      key = apk_key_map[name]
      if key not in common.SPECIAL_CERT_STRINGS:
        print "    signing: %-*s (%s)" % (maxsize, name, key)
        signed_data = SignApk(data, key, key_passwords[key], platform_api_level,
            codename_to_api_level_map)
        common.ZipWriteStr(output_tf_zip, out_info, signed_data)
      else:
        # an APK we're not supposed to sign.
        print "NOT signing: %s" % (name,)
        common.ZipWriteStr(output_tf_zip, out_info, data)

    # System properties.
    elif info.filename in ("SYSTEM/build.prop",
                           "VENDOR/build.prop",
                           "BOOT/RAMDISK/default.prop",
                           "ROOT/default.prop",
                           "RECOVERY/RAMDISK/default.prop"):
      print "rewriting %s:" % (info.filename,)
      new_data = RewriteProps(data, misc_info)
      common.ZipWriteStr(output_tf_zip, out_info, new_data)
      if info.filename in ("BOOT/RAMDISK/default.prop",
                           "ROOT/default.prop",
                           "RECOVERY/RAMDISK/default.prop"):
        write_to_temp(info.filename, info.external_attr, new_data)

    elif info.filename.endswith("mac_permissions.xml"):
      print "rewriting %s with new keys." % (info.filename,)
      new_data = ReplaceCerts(data)
      common.ZipWriteStr(output_tf_zip, out_info, new_data)

    # Trigger a rebuild of the recovery patch if needed.
    elif info.filename in ("SYSTEM/recovery-from-boot.p",
                           "SYSTEM/etc/recovery.img",
                           "SYSTEM/bin/install-recovery.sh"):
      rebuild_recovery = True

    # Don't copy OTA keys if we're replacing them.
    elif (OPTIONS.replace_ota_keys and
          info.filename in (
              "BOOT/RAMDISK/res/keys",
              "BOOT/RAMDISK/etc/update_engine/update-payload-key.pub.pem",
              "RECOVERY/RAMDISK/res/keys",
              "SYSTEM/etc/security/otacerts.zip",
              "SYSTEM/etc/update_engine/update-payload-key.pub.pem")):
      pass

    # Skip META/misc_info.txt if we will replace the verity private key later.
    elif (OPTIONS.replace_verity_private_key and
          info.filename == "META/misc_info.txt"):
      pass

    # Skip verity public key if we will replace it.
    elif (OPTIONS.replace_verity_public_key and
          info.filename in ("BOOT/RAMDISK/verity_key",
                            "ROOT/verity_key")):
      pass

    # Skip verity keyid (for system_root_image use) if we will replace it.
    elif (OPTIONS.replace_verity_keyid and
          info.filename == "BOOT/cmdline"):
      pass

    # Skip the care_map as we will regenerate the system/vendor images.
    elif (info.filename == "META/care_map.txt"):
      pass

    # Copy BOOT/, RECOVERY/, META/, ROOT/ to rebuild recovery patch. This case
    # must come AFTER other matching rules.
    elif (info.filename.startswith("BOOT/") or
          info.filename.startswith("RECOVERY/") or
          info.filename.startswith("META/") or
          info.filename.startswith("ROOT/") or
          info.filename == "SYSTEM/etc/recovery-resource.dat"):
      write_to_temp(info.filename, info.external_attr, data)
      common.ZipWriteStr(output_tf_zip, out_info, data)

    # A non-APK file; copy it verbatim.
    else:
      common.ZipWriteStr(output_tf_zip, out_info, data)

  if OPTIONS.replace_ota_keys:
    new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
    if new_recovery_keys:
      if system_root_image:
        recovery_keys_location = "BOOT/RAMDISK/res/keys"
      else:
        recovery_keys_location = "RECOVERY/RAMDISK/res/keys"
      # The "new_recovery_keys" has been already written into the output_tf_zip
      # while calling ReplaceOtaKeys(). We're just putting the same copy to
      # tmpdir in case we need to regenerate the recovery-from-boot patch.
      write_to_temp(recovery_keys_location, 0o755 << 16, new_recovery_keys)

  # Replace the keyid string in META/misc_info.txt.
  if OPTIONS.replace_verity_private_key:
    ReplaceVerityPrivateKey(input_tf_zip, output_tf_zip, misc_info,
                            OPTIONS.replace_verity_private_key[1])

  if OPTIONS.replace_verity_public_key:
    if system_root_image:
      dest = "ROOT/verity_key"
    else:
      dest = "BOOT/RAMDISK/verity_key"
    # We are replacing the one in boot image only, since the one under
    # recovery won't ever be needed.
    new_data = ReplaceVerityPublicKey(
        output_tf_zip, dest, OPTIONS.replace_verity_public_key[1])
    write_to_temp(dest, 0o755 << 16, new_data)

  # Replace the keyid string in BOOT/cmdline.
  if OPTIONS.replace_verity_keyid:
    new_cmdline = ReplaceVerityKeyId(input_tf_zip, output_tf_zip,
      OPTIONS.replace_verity_keyid[1])
    # Writing the new cmdline to tmpdir is redundant as the bootimage
    # gets build in the add_image_to_target_files and rebuild_recovery
    # is not exercised while building the boot image for the A/B
    # path
    write_to_temp("BOOT/cmdline", 0o755 << 16, new_cmdline)

  if rebuild_recovery:
    recovery_img = common.GetBootableImage(
        "recovery.img", "recovery.img", tmpdir, "RECOVERY", info_dict=misc_info)
    boot_img = common.GetBootableImage(
        "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)

    def output_sink(fn, data):
      common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data)

    common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
                             info_dict=misc_info)

  shutil.rmtree(tmpdir)
예제 #29
0
def AddImagesToTargetFiles(filename):
    OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
    OPTIONS.out_path = filename[0:filename.find("obj")]

    if not OPTIONS.add_missing:
        for n in input_zip.namelist():
            if n.startswith("IMAGES/"):
                print "target_files appears to already contain images."
                sys.exit(1)

    try:
        input_zip.getinfo("VENDOR/")
        has_vendor = True
    except KeyError:
        has_vendor = False

    OPTIONS.info_dict = common.LoadInfoDict(input_zip)

    # SPRD: add for secure boot
    OPTIONS.secure_boot = OPTIONS.info_dict.get("secure_boot", False)
    OPTIONS.secure_boot_tool = OPTIONS.info_dict.get("secure_boot_tool", None)
    OPTIONS.single_key = OPTIONS.info_dict.get("single_key", True)

    if "selinux_fc" in OPTIONS.info_dict:
        OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp,
                                                       "BOOT", "RAMDISK",
                                                       "file_contexts")

    common.ZipClose(input_zip)
    output_zip = zipfile.ZipFile(filename,
                                 "a",
                                 compression=zipfile.ZIP_DEFLATED)

    def banner(s):
        print "\n\n++++ " + s + " ++++\n\n"

    banner("boot")
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
    boot_image = None
    if os.path.exists(prebuilt_path):
        print "boot.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                                 OPTIONS.input_tmp, "BOOT")
    else:
        boot_image = common.GetBootableImage("IMAGES/boot.img", "boot.img",
                                             OPTIONS.input_tmp, "BOOT")
        if boot_image:
            boot_image.AddToZip(output_zip)

    banner("recovery")
    recovery_image = None
    prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
    if os.path.exists(prebuilt_path):
        print "recovery.img already exists in IMAGES/, no need to rebuild..."
        if OPTIONS.rebuild_recovery:
            recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                     "recovery.img",
                                                     OPTIONS.input_tmp,
                                                     "RECOVERY")
    else:
        recovery_image = common.GetBootableImage("IMAGES/recovery.img",
                                                 "recovery.img",
                                                 OPTIONS.input_tmp, "RECOVERY")
        if recovery_image:
            recovery_image.AddToZip(output_zip)

    banner("system")
    if not CopySystem(output_zip, filename):
        AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
    if has_vendor:
        banner("vendor")
        AddVendor(output_zip)
    banner("userdata")
    AddUserdata(output_zip)
    banner("cache")
    AddCache(output_zip)
    banner("usbmsc")
    AddUsbmsc(output_zip)
    common.ZipClose(output_zip)