Merge "Re-generate 4K boot OTAs using signed boot.img during signing process" into main
This commit is contained in:
@@ -108,7 +108,7 @@ python_defaults {
|
|||||||
python_library_host {
|
python_library_host {
|
||||||
name: "ota_metadata_proto",
|
name: "ota_metadata_proto",
|
||||||
srcs: [
|
srcs: [
|
||||||
"ota_metadata.proto",
|
"ota_metadata.proto",
|
||||||
],
|
],
|
||||||
proto: {
|
proto: {
|
||||||
canonical_path_from_root: false,
|
canonical_path_from_root: false,
|
||||||
@@ -118,7 +118,7 @@ python_library_host {
|
|||||||
cc_library_static {
|
cc_library_static {
|
||||||
name: "ota_metadata_proto_cc",
|
name: "ota_metadata_proto_cc",
|
||||||
srcs: [
|
srcs: [
|
||||||
"ota_metadata.proto",
|
"ota_metadata.proto",
|
||||||
],
|
],
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
@@ -145,7 +145,7 @@ java_library_static {
|
|||||||
static_libs: ["libprotobuf-java-nano"],
|
static_libs: ["libprotobuf-java-nano"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
visibility: ["//frameworks/base:__subpackages__"]
|
visibility: ["//frameworks/base:__subpackages__"],
|
||||||
}
|
}
|
||||||
|
|
||||||
python_defaults {
|
python_defaults {
|
||||||
@@ -437,7 +437,7 @@ python_binary_host {
|
|||||||
name: "check_target_files_vintf",
|
name: "check_target_files_vintf",
|
||||||
defaults: [
|
defaults: [
|
||||||
"releasetools_binary_defaults",
|
"releasetools_binary_defaults",
|
||||||
"releasetools_check_target_files_vintf_defaults"
|
"releasetools_check_target_files_vintf_defaults",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,13 +547,14 @@ python_binary_host {
|
|||||||
defaults: ["releasetools_binary_defaults"],
|
defaults: ["releasetools_binary_defaults"],
|
||||||
srcs: [
|
srcs: [
|
||||||
"sign_target_files_apks.py",
|
"sign_target_files_apks.py",
|
||||||
"payload_signer.py",
|
"ota_from_raw_img.py",
|
||||||
"ota_signing_utils.py",
|
|
||||||
],
|
],
|
||||||
libs: [
|
libs: [
|
||||||
"releasetools_add_img_to_target_files",
|
"releasetools_add_img_to_target_files",
|
||||||
"releasetools_apex_utils",
|
"releasetools_apex_utils",
|
||||||
"releasetools_common",
|
"releasetools_common",
|
||||||
|
"ota_metadata_proto",
|
||||||
|
"ota_utils_lib",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +634,7 @@ python_defaults {
|
|||||||
data: [
|
data: [
|
||||||
"testdata/**/*",
|
"testdata/**/*",
|
||||||
":com.android.apex.compressed.v1",
|
":com.android.apex.compressed.v1",
|
||||||
":com.android.apex.vendor.foo.with_vintf"
|
":com.android.apex.vendor.foo.with_vintf",
|
||||||
],
|
],
|
||||||
target: {
|
target: {
|
||||||
darwin: {
|
darwin: {
|
||||||
|
@@ -898,7 +898,7 @@ def LoadInfoDict(input_file, repacking=False):
|
|||||||
if key.endswith("selinux_fc"):
|
if key.endswith("selinux_fc"):
|
||||||
fc_basename = os.path.basename(d[key])
|
fc_basename = os.path.basename(d[key])
|
||||||
fc_config = os.path.join(input_file, "META", fc_basename)
|
fc_config = os.path.join(input_file, "META", fc_basename)
|
||||||
assert os.path.exists(fc_config)
|
assert os.path.exists(fc_config), "{} does not exist".format(fc_config)
|
||||||
|
|
||||||
d[key] = fc_config
|
d[key] = fc_config
|
||||||
|
|
||||||
@@ -3008,7 +3008,7 @@ def ZipWrite(zip_file, filename, arcname=None, perms=0o644,
|
|||||||
zipfile.ZIP64_LIMIT = saved_zip64_limit
|
zipfile.ZIP64_LIMIT = saved_zip64_limit
|
||||||
|
|
||||||
|
|
||||||
def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=None,
|
def ZipWriteStr(zip_file: zipfile.ZipFile, zinfo_or_arcname, data, perms=None,
|
||||||
compress_type=None):
|
compress_type=None):
|
||||||
"""Wrap zipfile.writestr() function to work around the zip64 limit.
|
"""Wrap zipfile.writestr() function to work around the zip64 limit.
|
||||||
|
|
||||||
|
@@ -189,6 +189,8 @@ import zipfile
|
|||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import add_img_to_target_files
|
import add_img_to_target_files
|
||||||
|
import ota_from_raw_img
|
||||||
|
import ota_utils
|
||||||
import apex_utils
|
import apex_utils
|
||||||
import common
|
import common
|
||||||
import payload_signer
|
import payload_signer
|
||||||
@@ -579,7 +581,61 @@ def IsBuildPropFile(filename):
|
|||||||
filename.endswith("/prop.default")
|
filename.endswith("/prop.default")
|
||||||
|
|
||||||
|
|
||||||
def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip, 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"""
|
||||||
|
if OPTIONS.input_tmp is None:
|
||||||
|
OPTIONS.input_tmp = common.UnzipTemp(input_tf_zip.filename, [
|
||||||
|
"*/boot.img", "*/dtbo.img"])
|
||||||
|
else:
|
||||||
|
common.UnzipToDir(input_tf_zip, OPTIONS.input_tmp, [
|
||||||
|
"*/boot.img", "*/dtbo.img"])
|
||||||
|
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(
|
||||||
|
"IMAGES/boot.img", "boot.img", unzip_dir, "BOOT", misc_info)
|
||||||
|
if boot_image:
|
||||||
|
boot_image.WriteToDir(unzip_dir)
|
||||||
|
boot_image = os.path.join(unzip_dir, boot_image.name)
|
||||||
|
common.ZipWrite(output_tf_zip, boot_image, "IMAGES/boot.img",
|
||||||
|
compress_type=zipfile.ZIP_STORED)
|
||||||
|
add_img_to_target_files.AddDtbo(output_tf_zip)
|
||||||
|
return unzip_dir
|
||||||
|
|
||||||
|
|
||||||
|
def RegenerateBootOTA(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.ZipFile, misc_info, filename, input_ota):
|
||||||
|
if filename not in ["VENDOR/boot_otas/boot_ota_4k.zip", "SYSTEM/boot_otas/boot_ota_4k.zip"]:
|
||||||
|
# We only need to re-generate 4K boot OTA, for other OTA packages
|
||||||
|
# simply copy as is
|
||||||
|
with input_tf_zip.open(filename, "r") as in_fp:
|
||||||
|
shutil.copyfileobj(in_fp, input_ota)
|
||||||
|
input_ota.flush()
|
||||||
|
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")
|
||||||
|
|
||||||
|
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.")
|
||||||
|
return
|
||||||
|
logger.info(
|
||||||
|
"Re-generating boot OTA {} with timestamp {}".format(filename, timestamp))
|
||||||
|
args = ["ota_from_raw_img", "--package_key", OPTIONS.package_key,
|
||||||
|
"--max_timestamp", timestamp, "--output", input_ota.name]
|
||||||
|
if os.path.exists(signed_dtbo_image):
|
||||||
|
args.extend(["--partition_name", "boot,dtbo",
|
||||||
|
signed_boot_image, signed_dtbo_image])
|
||||||
|
else:
|
||||||
|
args.extend(["--partition_name", "boot", signed_boot_image])
|
||||||
|
ota_from_raw_img.main(args)
|
||||||
|
|
||||||
|
|
||||||
|
def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip: zipfile.ZipFile, misc_info,
|
||||||
apk_keys, apex_keys, key_passwords,
|
apk_keys, apex_keys, key_passwords,
|
||||||
platform_api_level, codename_to_api_level_map,
|
platform_api_level, codename_to_api_level_map,
|
||||||
compressed_extension):
|
compressed_extension):
|
||||||
@@ -593,6 +649,14 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip, misc_info,
|
|||||||
# Sets this to zero for targets without APK files.
|
# Sets this to zero for targets without APK files.
|
||||||
maxsize = 0
|
maxsize = 0
|
||||||
|
|
||||||
|
# Replace the AVB signing keys, if any.
|
||||||
|
ReplaceAvbSigningKeys(misc_info)
|
||||||
|
OPTIONS.info_dict = misc_info
|
||||||
|
|
||||||
|
# Rewrite the props in AVB signing args.
|
||||||
|
if misc_info.get('avb_enable') == 'true':
|
||||||
|
RewriteAvbProps(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/"):
|
||||||
@@ -670,9 +734,9 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip, misc_info,
|
|||||||
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:
|
||||||
with input_tf_zip.open(filename, "r") as in_fp:
|
RegenerateBootOTA(input_tf_zip, output_tf_zip,
|
||||||
shutil.copyfileobj(in_fp, input_ota)
|
misc_info, filename, input_ota)
|
||||||
input_ota.flush()
|
|
||||||
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,
|
||||||
compress_type=zipfile.ZIP_STORED)
|
compress_type=zipfile.ZIP_STORED)
|
||||||
@@ -811,17 +875,18 @@ def ProcessTargetFiles(input_tf_zip: zipfile.ZipFile, output_tf_zip, misc_info,
|
|||||||
common.ZipWrite(output_tf_zip, image.name, filename)
|
common.ZipWrite(output_tf_zip, image.name, filename)
|
||||||
# A non-APK file; copy it verbatim.
|
# A non-APK file; copy it verbatim.
|
||||||
else:
|
else:
|
||||||
common.ZipWriteStr(output_tf_zip, out_info, data)
|
try:
|
||||||
|
entry = output_tf_zip.getinfo(filename)
|
||||||
|
if output_tf_zip.read(entry) != data:
|
||||||
|
logger.warn(
|
||||||
|
"Output zip contains duplicate entries for %s with different contents", filename)
|
||||||
|
continue
|
||||||
|
except KeyError:
|
||||||
|
common.ZipWriteStr(output_tf_zip, out_info, data)
|
||||||
|
|
||||||
if OPTIONS.replace_ota_keys:
|
if OPTIONS.replace_ota_keys:
|
||||||
ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
|
ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
|
||||||
|
|
||||||
# Replace the AVB signing keys, if any.
|
|
||||||
ReplaceAvbSigningKeys(misc_info)
|
|
||||||
|
|
||||||
# Rewrite the props in AVB signing args.
|
|
||||||
if misc_info.get('avb_enable') == 'true':
|
|
||||||
RewriteAvbProps(misc_info)
|
|
||||||
|
|
||||||
# Write back misc_info with the latest values.
|
# Write back misc_info with the latest values.
|
||||||
ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)
|
ReplaceMiscInfoTxt(input_tf_zip, output_tf_zip, misc_info)
|
||||||
|
Reference in New Issue
Block a user