Merge "Reland Support incremental dev option OTA during signing" into main am: 7f9092291f
am: 7575a8174b
Original change: https://android-review.googlesource.com/c/platform/build/+/3257139 Change-Id: Ie8b1e4c4a964549dbbc383921ec1e1a208fcc1ae Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -555,6 +555,7 @@ python_binary_host {
|
|||||||
"releasetools_common",
|
"releasetools_common",
|
||||||
"ota_metadata_proto",
|
"ota_metadata_proto",
|
||||||
"ota_utils_lib",
|
"ota_utils_lib",
|
||||||
|
"update_payload",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -190,10 +190,10 @@ from xml.etree import ElementTree
|
|||||||
|
|
||||||
import add_img_to_target_files
|
import add_img_to_target_files
|
||||||
import ota_from_raw_img
|
import ota_from_raw_img
|
||||||
import ota_utils
|
|
||||||
import apex_utils
|
import apex_utils
|
||||||
import common
|
import common
|
||||||
import payload_signer
|
import payload_signer
|
||||||
|
import update_payload
|
||||||
from payload_signer import SignOtaPackage, PAYLOAD_BIN
|
from payload_signer import SignOtaPackage, PAYLOAD_BIN
|
||||||
|
|
||||||
|
|
||||||
@@ -223,6 +223,7 @@ OPTIONS.vendor_otatools = None
|
|||||||
OPTIONS.allow_gsi_debug_sepolicy = False
|
OPTIONS.allow_gsi_debug_sepolicy = False
|
||||||
OPTIONS.override_apk_keys = None
|
OPTIONS.override_apk_keys = None
|
||||||
OPTIONS.override_apex_keys = None
|
OPTIONS.override_apex_keys = None
|
||||||
|
OPTIONS.input_tmp = None
|
||||||
|
|
||||||
|
|
||||||
AVB_FOOTER_ARGS_BY_PARTITION = {
|
AVB_FOOTER_ARGS_BY_PARTITION = {
|
||||||
@@ -583,16 +584,13 @@ def IsBuildPropFile(filename):
|
|||||||
|
|
||||||
def RegenerateKernelPartitions(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.ZipFile, misc_info):
|
def RegenerateKernelPartitions(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.ZipFile, misc_info):
|
||||||
"""Re-generate boot and dtbo partitions using new signing configuration"""
|
"""Re-generate boot and dtbo partitions using new signing configuration"""
|
||||||
|
files_to_unzip = [
|
||||||
|
"PREBUILT_IMAGES/*", "BOOTABLE_IMAGES/*.img", "*/boot_16k.img", "*/dtbo_16k.img"]
|
||||||
if OPTIONS.input_tmp is None:
|
if OPTIONS.input_tmp is None:
|
||||||
OPTIONS.input_tmp = common.UnzipTemp(input_tf_zip.filename, [
|
OPTIONS.input_tmp = common.UnzipTemp(input_tf_zip.filename, files_to_unzip)
|
||||||
"*/boot.img", "*/dtbo.img"])
|
|
||||||
else:
|
else:
|
||||||
common.UnzipToDir(input_tf_zip, OPTIONS.input_tmp, [
|
common.UnzipToDir(input_tf_zip.filename, OPTIONS.input_tmp, files_to_unzip)
|
||||||
"*/boot.img", "*/dtbo.img"])
|
|
||||||
unzip_dir = OPTIONS.input_tmp
|
unzip_dir = OPTIONS.input_tmp
|
||||||
image_dir = os.path.join(unzip_dir, "IMAGES")
|
|
||||||
shutil.rmtree(image_dir)
|
|
||||||
os.makedirs(image_dir, exist_ok=True)
|
|
||||||
|
|
||||||
boot_image = common.GetBootableImage(
|
boot_image = common.GetBootableImage(
|
||||||
"IMAGES/boot.img", "boot.img", unzip_dir, "BOOT", misc_info)
|
"IMAGES/boot.img", "boot.img", unzip_dir, "BOOT", misc_info)
|
||||||
@@ -601,37 +599,64 @@ def RegenerateKernelPartitions(input_tf_zip: zipfile.ZipFile, output_tf_zip: zip
|
|||||||
boot_image = os.path.join(unzip_dir, boot_image.name)
|
boot_image = os.path.join(unzip_dir, boot_image.name)
|
||||||
common.ZipWrite(output_tf_zip, boot_image, "IMAGES/boot.img",
|
common.ZipWrite(output_tf_zip, boot_image, "IMAGES/boot.img",
|
||||||
compress_type=zipfile.ZIP_STORED)
|
compress_type=zipfile.ZIP_STORED)
|
||||||
add_img_to_target_files.AddDtbo(output_tf_zip)
|
if misc_info.get("has_dtbo") == "true":
|
||||||
|
add_img_to_target_files.AddDtbo(output_tf_zip)
|
||||||
return unzip_dir
|
return unzip_dir
|
||||||
|
|
||||||
|
|
||||||
def RegenerateBootOTA(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.ZipFile, misc_info, filename, input_ota):
|
def RegenerateBootOTA(input_tf_zip: zipfile.ZipFile, filename, input_ota):
|
||||||
if filename not in ["VENDOR/boot_otas/boot_ota_4k.zip", "SYSTEM/boot_otas/boot_ota_4k.zip"]:
|
with input_tf_zip.open(filename, "r") as in_fp:
|
||||||
# We only need to re-generate 4K boot OTA, for other OTA packages
|
payload = update_payload.Payload(in_fp)
|
||||||
# simply copy as is
|
is_incremental = any([part.HasField('old_partition_info')
|
||||||
with input_tf_zip.open(filename, "r") as in_fp:
|
for part in payload.manifest.partitions])
|
||||||
shutil.copyfileobj(in_fp, input_ota)
|
is_boot_ota = filename.startswith(
|
||||||
input_ota.flush()
|
"VENDOR/boot_otas/") or filename.startswith("SYSTEM/boot_otas/")
|
||||||
|
if not is_boot_ota:
|
||||||
|
return
|
||||||
|
is_4k_boot_ota = filename in [
|
||||||
|
"VENDOR/boot_otas/boot_ota_4k.zip", "SYSTEM/boot_otas/boot_ota_4k.zip"]
|
||||||
|
# Only 4K boot image is re-generated, so if 16K boot ota isn't incremental,
|
||||||
|
# we do not need to re-generate
|
||||||
|
if not is_4k_boot_ota and not is_incremental:
|
||||||
return
|
return
|
||||||
timestamp = misc_info["build.prop"].GetProp(
|
|
||||||
"ro.system.build.date.utc")
|
|
||||||
unzip_dir = RegenerateKernelPartitions(
|
|
||||||
input_tf_zip, output_tf_zip, misc_info)
|
|
||||||
signed_boot_image = os.path.join(unzip_dir, "IMAGES/boot.img")
|
|
||||||
signed_dtbo_image = os.path.join(unzip_dir, "IMAGES/dtbo.img")
|
|
||||||
|
|
||||||
|
timestamp = str(payload.manifest.max_timestamp)
|
||||||
|
partitions = [part.partition_name for part in payload.manifest.partitions]
|
||||||
|
unzip_dir = OPTIONS.input_tmp
|
||||||
|
signed_boot_image = os.path.join(unzip_dir, "IMAGES", "boot.img")
|
||||||
if not os.path.exists(signed_boot_image):
|
if not os.path.exists(signed_boot_image):
|
||||||
logger.warn("Need to re-generate boot OTA {} but failed to get signed boot image. 16K dev option will be impacted, after rolling back to 4K user would need to sideload/flash their device to continue receiving OTAs.")
|
logger.warn("Need to re-generate boot OTA {} but failed to get signed boot image. 16K dev option will be impacted, after rolling back to 4K user would need to sideload/flash their device to continue receiving OTAs.")
|
||||||
return
|
return
|
||||||
logger.info(
|
signed_dtbo_image = os.path.join(unzip_dir, "IMAGES", "dtbo.img")
|
||||||
"Re-generating boot OTA {} with timestamp {}".format(filename, timestamp))
|
if "dtbo" in partitions and not os.path.exists(signed_dtbo_image):
|
||||||
|
raise ValueError(
|
||||||
|
"Boot OTA {} has dtbo partition, but no dtbo image found in target files.".format(filename))
|
||||||
|
if is_incremental:
|
||||||
|
signed_16k_boot_image = os.path.join(
|
||||||
|
unzip_dir, "IMAGES", "boot_16k.img")
|
||||||
|
signed_16k_dtbo_image = os.path.join(
|
||||||
|
unzip_dir, "IMAGES", "dtbo_16k.img")
|
||||||
|
if is_4k_boot_ota:
|
||||||
|
if os.path.exists(signed_16k_boot_image):
|
||||||
|
signed_boot_image = signed_16k_boot_image + ":" + signed_boot_image
|
||||||
|
if os.path.exists(signed_16k_dtbo_image):
|
||||||
|
signed_dtbo_image = signed_16k_dtbo_image + ":" + signed_dtbo_image
|
||||||
|
else:
|
||||||
|
if os.path.exists(signed_16k_boot_image):
|
||||||
|
signed_boot_image += ":" + signed_16k_boot_image
|
||||||
|
if os.path.exists(signed_16k_dtbo_image):
|
||||||
|
signed_dtbo_image += ":" + signed_16k_dtbo_image
|
||||||
|
|
||||||
|
|
||||||
args = ["ota_from_raw_img", "--package_key", OPTIONS.package_key,
|
args = ["ota_from_raw_img", "--package_key", OPTIONS.package_key,
|
||||||
"--max_timestamp", timestamp, "--output", input_ota.name]
|
"--max_timestamp", timestamp, "--output", input_ota.name]
|
||||||
if os.path.exists(signed_dtbo_image):
|
if "dtbo" in partitions:
|
||||||
args.extend(["--partition_name", "boot,dtbo",
|
args.extend(["--partition_name", "boot,dtbo",
|
||||||
signed_boot_image, signed_dtbo_image])
|
signed_boot_image, signed_dtbo_image])
|
||||||
else:
|
else:
|
||||||
args.extend(["--partition_name", "boot", signed_boot_image])
|
args.extend(["--partition_name", "boot", signed_boot_image])
|
||||||
|
logger.info(
|
||||||
|
"Re-generating boot OTA {} using cmd {}".format(filename, args))
|
||||||
ota_from_raw_img.main(args)
|
ota_from_raw_img.main(args)
|
||||||
|
|
||||||
|
|
||||||
@@ -657,6 +682,8 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.Zip
|
|||||||
if misc_info.get('avb_enable') == 'true':
|
if misc_info.get('avb_enable') == 'true':
|
||||||
RewriteAvbProps(misc_info)
|
RewriteAvbProps(misc_info)
|
||||||
|
|
||||||
|
RegenerateKernelPartitions(input_tf_zip, output_tf_zip, misc_info)
|
||||||
|
|
||||||
for info in input_tf_zip.infolist():
|
for info in input_tf_zip.infolist():
|
||||||
filename = info.filename
|
filename = info.filename
|
||||||
if filename.startswith("IMAGES/"):
|
if filename.startswith("IMAGES/"):
|
||||||
@@ -667,10 +694,10 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.Zip
|
|||||||
if filename.startswith("OTA/") and filename.endswith(".img"):
|
if filename.startswith("OTA/") and filename.endswith(".img"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
data = input_tf_zip.read(filename)
|
|
||||||
out_info = copy.copy(info)
|
|
||||||
(is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
|
(is_apk, is_compressed, should_be_skipped) = GetApkFileInfo(
|
||||||
filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
|
filename, compressed_extension, OPTIONS.skip_apks_with_path_prefix)
|
||||||
|
data = input_tf_zip.read(filename)
|
||||||
|
out_info = copy.copy(info)
|
||||||
|
|
||||||
if is_apk and should_be_skipped:
|
if is_apk and should_be_skipped:
|
||||||
# Copy skipped APKs verbatim.
|
# Copy skipped APKs verbatim.
|
||||||
@@ -734,8 +761,7 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.Zip
|
|||||||
elif filename.endswith(".zip") and IsEntryOtaPackage(input_tf_zip, filename):
|
elif filename.endswith(".zip") and IsEntryOtaPackage(input_tf_zip, filename):
|
||||||
logger.info("Re-signing OTA package {}".format(filename))
|
logger.info("Re-signing OTA package {}".format(filename))
|
||||||
with tempfile.NamedTemporaryFile() as input_ota, tempfile.NamedTemporaryFile() as output_ota:
|
with tempfile.NamedTemporaryFile() as input_ota, tempfile.NamedTemporaryFile() as output_ota:
|
||||||
RegenerateBootOTA(input_tf_zip, output_tf_zip,
|
RegenerateBootOTA(input_tf_zip, filename, input_ota)
|
||||||
misc_info, filename, input_ota)
|
|
||||||
|
|
||||||
SignOtaPackage(input_ota.name, output_ota.name)
|
SignOtaPackage(input_ota.name, output_ota.name)
|
||||||
common.ZipWrite(output_tf_zip, output_ota.name, filename,
|
common.ZipWrite(output_tf_zip, output_ota.name, filename,
|
||||||
|
Reference in New Issue
Block a user