Merge "releasetools: Add NonAbOtaPropertyFiles for non-A/B OTA packages." am: 93a84dd9a6
am: f13591bbb3
Change-Id: I43114d7b8ce5900e706e9f234c0fe67cff7cf268
This commit is contained in:
@@ -705,7 +705,7 @@ def AddCompatibilityArchiveIfTrebleEnabled(target_zip, output_zip, target_info,
|
|||||||
AddCompatibilityArchive(system_updated, vendor_updated)
|
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)
|
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
|
# We don't know what version it will be installed on top of. We expect the API
|
||||||
@@ -719,6 +719,14 @@ def WriteFullOTAPackage(input_zip, output_zip):
|
|||||||
|
|
||||||
metadata = GetPackageMetadata(target_info)
|
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(
|
device_specific = common.DeviceSpecificParams(
|
||||||
input_zip=input_zip,
|
input_zip=input_zip,
|
||||||
input_version=target_api_version,
|
input_version=target_api_version,
|
||||||
@@ -863,7 +871,15 @@ endif;
|
|||||||
script.SetProgress(1)
|
script.SetProgress(1)
|
||||||
script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
|
script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
|
||||||
metadata["ota-required-cache"] = str(script.required_cache)
|
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):
|
def WriteMetadata(metadata, output_zip):
|
||||||
@@ -1203,6 +1219,19 @@ class AbOtaPropertyFiles(StreamingPropertyFiles):
|
|||||||
return (payload_offset, metadata_total)
|
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):
|
def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
|
||||||
"""Finalizes the metadata and signs an A/B OTA package.
|
"""Finalizes the metadata and signs an A/B OTA package.
|
||||||
|
|
||||||
@@ -1237,8 +1266,11 @@ def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
|
|||||||
# signing (with an incomplete metadata entry) to allow that to happen. Then
|
# 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
|
# compute the ZIP entry offsets, write back the final metadata and do the
|
||||||
# final signing.
|
# final signing.
|
||||||
prelim_signing = common.MakeTempFile(suffix='.zip')
|
if OPTIONS.no_signing:
|
||||||
SignOutput(input_file, prelim_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.
|
# Open the signed zip. Compute the final metadata that's needed for streaming.
|
||||||
with zipfile.ZipFile(prelim_signing, 'r') as prelim_signing_zip:
|
with zipfile.ZipFile(prelim_signing, 'r') as prelim_signing_zip:
|
||||||
@@ -1254,7 +1286,10 @@ def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
|
|||||||
common.ZipClose(output_zip)
|
common.ZipClose(output_zip)
|
||||||
|
|
||||||
# Re-sign the package after updating the metadata entry.
|
# 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.
|
# Reopen the final signed zip to double check the streaming metadata.
|
||||||
with zipfile.ZipFile(output_file, 'r') as output_zip:
|
with zipfile.ZipFile(output_file, 'r') as output_zip:
|
||||||
@@ -1262,7 +1297,7 @@ def FinalizeMetadata(metadata, input_file, output_file, needed_property_files):
|
|||||||
property_files.Verify(output_zip, metadata[property_files.name].strip())
|
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)
|
target_info = BuildInfo(OPTIONS.target_info_dict, OPTIONS.oem_dicts)
|
||||||
source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
|
source_info = BuildInfo(OPTIONS.source_info_dict, OPTIONS.oem_dicts)
|
||||||
|
|
||||||
@@ -1281,6 +1316,14 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
|
|
||||||
metadata = GetPackageMetadata(target_info, source_info)
|
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(
|
device_specific = common.DeviceSpecificParams(
|
||||||
source_zip=source_zip,
|
source_zip=source_zip,
|
||||||
source_version=source_api_version,
|
source_version=source_api_version,
|
||||||
@@ -1530,7 +1573,16 @@ endif;
|
|||||||
else:
|
else:
|
||||||
script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
|
script.AddToZip(target_zip, output_zip, input_path=OPTIONS.updater_binary)
|
||||||
metadata["ota-required-cache"] = str(script.required_cache)
|
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):
|
def GetTargetFilesZipForSecondaryImages(input_file, skip_postinstall=False):
|
||||||
@@ -1610,7 +1662,10 @@ def WriteABOTAPackageWithBrilloScript(target_file, output_file,
|
|||||||
source_file=None):
|
source_file=None):
|
||||||
"""Generates an Android OTA package that has A/B update payload."""
|
"""Generates an Android OTA package that has A/B update payload."""
|
||||||
# Stage the output zip package for package signing.
|
# 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",
|
output_zip = zipfile.ZipFile(staging_file, "w",
|
||||||
compression=zipfile.ZIP_DEFLATED)
|
compression=zipfile.ZIP_DEFLATED)
|
||||||
|
|
||||||
@@ -1892,21 +1947,12 @@ def main(argv):
|
|||||||
if OPTIONS.device_specific is not None:
|
if OPTIONS.device_specific is not None:
|
||||||
OPTIONS.device_specific = os.path.abspath(OPTIONS.device_specific)
|
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.
|
# Generate a full OTA.
|
||||||
if OPTIONS.incremental_source is None:
|
if OPTIONS.incremental_source is None:
|
||||||
with zipfile.ZipFile(args[0], 'r') as input_zip:
|
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.
|
# Generate an incremental OTA.
|
||||||
else:
|
else:
|
||||||
@@ -1915,7 +1961,10 @@ def main(argv):
|
|||||||
OPTIONS.incremental_source, UNZIP_PATTERN)
|
OPTIONS.incremental_source, UNZIP_PATTERN)
|
||||||
with zipfile.ZipFile(args[0], 'r') as input_zip, \
|
with zipfile.ZipFile(args[0], 'r') as input_zip, \
|
||||||
zipfile.ZipFile(OPTIONS.incremental_source, 'r') as source_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:
|
if OPTIONS.log_diff:
|
||||||
with open(OPTIONS.log_diff, 'w') as out_file:
|
with open(OPTIONS.log_diff, 'w') as out_file:
|
||||||
@@ -1923,13 +1972,6 @@ def main(argv):
|
|||||||
target_files_diff.recursiveDiff(
|
target_files_diff.recursiveDiff(
|
||||||
'', OPTIONS.source_tmp, OPTIONS.input_tmp, out_file)
|
'', 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.")
|
print("done.")
|
||||||
|
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ import test_utils
|
|||||||
from ota_from_target_files import (
|
from ota_from_target_files import (
|
||||||
_LoadOemDicts, AbOtaPropertyFiles, BuildInfo, GetPackageMetadata,
|
_LoadOemDicts, AbOtaPropertyFiles, BuildInfo, GetPackageMetadata,
|
||||||
GetTargetFilesZipForSecondaryImages,
|
GetTargetFilesZipForSecondaryImages,
|
||||||
GetTargetFilesZipWithoutPostinstallConfig,
|
GetTargetFilesZipWithoutPostinstallConfig, NonAbOtaPropertyFiles,
|
||||||
Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
|
Payload, PayloadSigner, POSTINSTALL_CONFIG, PropertyFiles,
|
||||||
StreamingPropertyFiles, WriteFingerprintAssertion)
|
StreamingPropertyFiles, WriteFingerprintAssertion)
|
||||||
|
|
||||||
@@ -990,6 +990,58 @@ class AbOtaPropertyFilesTest(PropertyFilesTest):
|
|||||||
property_files.Verify(zip_fp, raw_metadata)
|
property_files.Verify(zip_fp, raw_metadata)
|
||||||
|
|
||||||
|
|
||||||
|
class NonAbOtaPropertyFilesTest(PropertyFilesTest):
|
||||||
|
"""Additional sanity checks specialized for NonAbOtaPropertyFiles."""
|
||||||
|
|
||||||
|
def test_init(self):
|
||||||
|
property_files = NonAbOtaPropertyFiles()
|
||||||
|
self.assertEqual('ota-property-files', property_files.name)
|
||||||
|
self.assertEqual((), property_files.required)
|
||||||
|
self.assertEqual((), property_files.optional)
|
||||||
|
|
||||||
|
def test_Compute(self):
|
||||||
|
entries = ()
|
||||||
|
zip_file = self._construct_zip_package(entries)
|
||||||
|
property_files = NonAbOtaPropertyFiles()
|
||||||
|
with zipfile.ZipFile(zip_file) as zip_fp:
|
||||||
|
property_files_string = property_files.Compute(zip_fp)
|
||||||
|
|
||||||
|
tokens = self._parse_property_files_string(property_files_string)
|
||||||
|
self.assertEqual(1, len(tokens))
|
||||||
|
self._verify_entries(zip_file, tokens, entries)
|
||||||
|
|
||||||
|
def test_Finalize(self):
|
||||||
|
entries = [
|
||||||
|
'META-INF/com/android/metadata',
|
||||||
|
]
|
||||||
|
zip_file = self._construct_zip_package(entries)
|
||||||
|
property_files = NonAbOtaPropertyFiles()
|
||||||
|
with zipfile.ZipFile(zip_file) as zip_fp:
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
raw_metadata = property_files._GetPropertyFilesString(
|
||||||
|
zip_fp, reserve_space=False)
|
||||||
|
property_files_string = property_files.Finalize(zip_fp, len(raw_metadata))
|
||||||
|
tokens = self._parse_property_files_string(property_files_string)
|
||||||
|
|
||||||
|
self.assertEqual(1, len(tokens))
|
||||||
|
# 'META-INF/com/android/metadata' will be key'd as 'metadata'.
|
||||||
|
entries[0] = 'metadata'
|
||||||
|
self._verify_entries(zip_file, tokens, entries)
|
||||||
|
|
||||||
|
def test_Verify(self):
|
||||||
|
entries = (
|
||||||
|
'META-INF/com/android/metadata',
|
||||||
|
)
|
||||||
|
zip_file = self._construct_zip_package(entries)
|
||||||
|
property_files = NonAbOtaPropertyFiles()
|
||||||
|
with zipfile.ZipFile(zip_file) as zip_fp:
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
raw_metadata = property_files._GetPropertyFilesString(
|
||||||
|
zip_fp, reserve_space=False)
|
||||||
|
|
||||||
|
property_files.Verify(zip_fp, raw_metadata)
|
||||||
|
|
||||||
|
|
||||||
class PayloadSignerTest(unittest.TestCase):
|
class PayloadSignerTest(unittest.TestCase):
|
||||||
|
|
||||||
SIGFILE = 'sigfile.bin'
|
SIGFILE = 'sigfile.bin'
|
||||||
|
Reference in New Issue
Block a user