releasetools: Add NonAbOtaPropertyFiles for non-A/B OTA packages.
This CL exposes ota-property-files flag for non-A/B OTA packages.
Currently the line only contains the info for the METADATA entry, for
example "ota-property-files=metadata:69:286". This allows system updater
to just download the METADATA entry, as opposed to downloading the
entire package, to learn about the info regarding the OTA package (e.g.
post-OTA build fingerprint). Note that this requires the OTA server-side
support to pass down the flag along with the update URL.
Bug: 74210298
Test: python -m unittest test_ota_from_target_files
Test: Generate a non-A/B package and check the property-files string.
Change-Id: I1482c587e18ea7101c8328777ea988c2d8ca06ac
Merged-In: I1482c587e18ea7101c8328777ea988c2d8ca06ac
(cherry picked from commit c0746f4e944981a944349bc4645b546a47eb9e58)
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 17e63d1..3579645 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -705,7 +705,7 @@
AddCompatibilityArchive(system_updated, vendor_updated)
-def WriteFullOTAPackage(input_zip, output_zip):
+def WriteFullOTAPackage(input_zip, output_file):
target_info = BuildInfo(OPTIONS.info_dict, OPTIONS.oem_dicts)
# We don't know what version it will be installed on top of. We expect the API
@@ -719,6 +719,14 @@
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,
@@ -863,7 +871,15 @@
script.SetProgress(1)
script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
metadata["ota-required-cache"] = str(script.required_cache)
- WriteMetadata(metadata, output_zip)
+
+ # 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 WriteMetadata(metadata, output_zip):
@@ -1203,6 +1219,19 @@
return (payload_offset, metadata_total)
+class NonAbOtaPropertyFiles(PropertyFiles):
+ """The property-files for non-A/B OTA.
+
+ For non-A/B OTA, the property-files string contains the info for METADATA
+ entry, with which a system updater can be fetched the package metadata prior
+ to downloading the entire package.
+ """
+
+ def __init__(self):
+ super(NonAbOtaPropertyFiles, self).__init__()
+ self.name = 'ota-property-files'
+
+
def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
"""Finalizes the metadata and signs an A/B OTA package.
@@ -1237,8 +1266,11 @@
# signing (with an incomplete metadata entry) to allow that to happen. Then
# compute the ZIP entry offsets, write back the final metadata and do the
# final signing.
- prelim_signing = common.MakeTempFile(suffix='.zip')
- SignOutput(input_file, prelim_signing)
+ if OPTIONS.no_signing:
+ prelim_signing = input_file
+ else:
+ prelim_signing = common.MakeTempFile(suffix='.zip')
+ SignOutput(input_file, prelim_signing)
# Open the signed zip. Compute the final metadata that's needed for streaming.
with zipfile.ZipFile(prelim_signing, 'r') as prelim_signing_zip:
@@ -1254,7 +1286,10 @@
common.ZipClose(output_zip)
# Re-sign the package after updating the metadata entry.
- SignOutput(prelim_signing, output_file)
+ if OPTIONS.no_signing:
+ output_file = prelim_signing
+ else:
+ SignOutput(prelim_signing, output_file)
# Reopen the final signed zip to double check the streaming metadata.
with zipfile.ZipFile(output_file, 'r') as output_zip:
@@ -1262,7 +1297,7 @@
property_files.Verify(output_zip, metadata[property_files.name].strip())
-def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
+def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_file):
target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
@@ -1281,6 +1316,14 @@
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,
@@ -1530,7 +1573,16 @@
else:
script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
metadata["ota-required-cache"] = str(script.required_cache)
- WriteMetadata(metadata, output_zip)
+
+ # 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 GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False):
@@ -1610,7 +1662,10 @@
source_file=None):
"""Generates an Android OTA package that has A/B update payload."""
# Stage the output zip package for package signing.
- staging_file = common.MakeTempFile(suffix='.zip')
+ 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)
@@ -1892,21 +1947,12 @@
if OPTIONS.device_specific is not None:
OPTIONS.device_specific = os.path.abspath(OPTIONS.device_specific)
- # Set up the output zip. Create a temporary zip file if signing is needed.
- if OPTIONS.no_signing:
- if os.path.exists(args[1]):
- os.unlink(args[1])
- output_zip = zipfile.ZipFile(args[1], "w",
- compression=zipfile.ZIP_DEFLATED)
- else:
- temp_zip_file = tempfile.NamedTemporaryFile()
- output_zip = zipfile.ZipFile(temp_zip_file, "w",
- compression=zipfile.ZIP_DEFLATED)
-
# Generate a full OTA.
if OPTIONS.incremental_source is None:
with zipfile.ZipFile(args[0], 'r') as input_zip:
- WriteFullOTAPackage(input_zip, output_zip)
+ WriteFullOTAPackage(
+ input_zip,
+ output_file=args[1])
# Generate an incremental OTA.
else:
@@ -1915,7 +1961,10 @@
OPTIONS.incremental_source, UNZIP_PATTERN)
with zipfile.ZipFile(args[0], 'r') as input_zip, \
zipfile.ZipFile(OPTIONS.incremental_source, 'r') as source_zip:
- WriteBlockIncrementalOTAPackage(input_zip, source_zip, output_zip)
+ WriteBlockIncrementalOTAPackage(
+ input_zip,
+ source_zip,
+ output_file=args[1])
if OPTIONS.log_diff:
with open(OPTIONS.log_diff, 'w') as out_file:
@@ -1923,13 +1972,6 @@
target_files_diff.recursiveDiff(
'', OPTIONS.source_tmp, OPTIONS.input_tmp, out_file)
- common.ZipClose(output_zip)
-
- # Sign the generated zip package unless no_signing is specified.
- if not OPTIONS.no_signing:
- SignOutput(temp_zip_file.name, args[1])
- temp_zip_file.close()
-
print("done.")