forked from openkylin/platform_build
Merge "releasetools: Add common.ZipDelete()."
am: 23f7ea9e70
Change-Id: I3a7d811a3b7589d324168c0c6afaf62438fda5b5
This commit is contained in:
commit
2bc1b967c1
|
@ -467,16 +467,12 @@ def AddCache(output_zip, prefix="IMAGES/"):
|
||||||
|
|
||||||
|
|
||||||
def ReplaceUpdatedFiles(zip_filename, files_list):
|
def ReplaceUpdatedFiles(zip_filename, files_list):
|
||||||
"""Update all the zip entries listed in the files_list.
|
"""Updates all the ZIP entries listed in files_list.
|
||||||
|
|
||||||
For now the list includes META/care_map.txt, and the related files under
|
For now the list includes META/care_map.txt, and the related files under
|
||||||
SYSTEM/ after rebuilding recovery.
|
SYSTEM/ after rebuilding recovery.
|
||||||
"""
|
"""
|
||||||
|
common.ZipDelete(zip_filename, files_list)
|
||||||
cmd = ["zip", "-d", zip_filename] + files_list
|
|
||||||
p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
||||||
p.communicate()
|
|
||||||
|
|
||||||
output_zip = zipfile.ZipFile(zip_filename, "a",
|
output_zip = zipfile.ZipFile(zip_filename, "a",
|
||||||
compression=zipfile.ZIP_DEFLATED,
|
compression=zipfile.ZIP_DEFLATED,
|
||||||
allowZip64=True)
|
allowZip64=True)
|
||||||
|
|
|
@ -1147,6 +1147,28 @@ def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=None,
|
||||||
zipfile.ZIP64_LIMIT = saved_zip64_limit
|
zipfile.ZIP64_LIMIT = saved_zip64_limit
|
||||||
|
|
||||||
|
|
||||||
|
def ZipDelete(zip_filename, entries):
|
||||||
|
"""Deletes entries from a ZIP file.
|
||||||
|
|
||||||
|
Since deleting entries from a ZIP file is not supported, it shells out to
|
||||||
|
'zip -d'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
zip_filename: The name of the ZIP file.
|
||||||
|
entries: The name of the entry, or the list of names to be deleted.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
AssertionError: In case of non-zero return from 'zip'.
|
||||||
|
"""
|
||||||
|
if isinstance(entries, basestring):
|
||||||
|
entries = [entries]
|
||||||
|
cmd = ["zip", "-d", zip_filename] + entries
|
||||||
|
proc = Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
stdoutdata, _ = proc.communicate()
|
||||||
|
assert proc.returncode == 0, "Failed to delete %s:\n%s" % (entries,
|
||||||
|
stdoutdata)
|
||||||
|
|
||||||
|
|
||||||
def ZipClose(zip_file):
|
def ZipClose(zip_file):
|
||||||
# http://b/18015246
|
# http://b/18015246
|
||||||
# zipfile also refers to ZIP64_LIMIT during close() when it writes out the
|
# zipfile also refers to ZIP64_LIMIT during close() when it writes out the
|
||||||
|
|
|
@ -137,7 +137,6 @@ if sys.hexversion < 0x02070000:
|
||||||
print("Python 2.7 or newer is required.", file=sys.stderr)
|
print("Python 2.7 or newer is required.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
import copy
|
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -1239,44 +1238,33 @@ def WriteABOTAPackageWithBrilloScript(target_file, output_file,
|
||||||
common.ZipClose(output_zip)
|
common.ZipClose(output_zip)
|
||||||
|
|
||||||
# SignOutput(), which in turn calls signapk.jar, will possibly reorder the
|
# SignOutput(), which in turn calls signapk.jar, will possibly reorder the
|
||||||
# zip entries, as well as padding the entry headers. We do a preliminary
|
# ZIP entries, as well as padding the entry headers. We do a preliminary
|
||||||
# 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 = tempfile.NamedTemporaryFile()
|
prelim_signing = common.MakeTempFile(suffix='.zip')
|
||||||
SignOutput(temp_zip_file.name, prelim_signing.name)
|
SignOutput(temp_zip_file.name, prelim_signing)
|
||||||
common.ZipClose(temp_zip_file)
|
common.ZipClose(temp_zip_file)
|
||||||
|
|
||||||
# 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.
|
||||||
prelim_zip = zipfile.ZipFile(prelim_signing, "r",
|
prelim_signing_zip = zipfile.ZipFile(prelim_signing, 'r')
|
||||||
compression=zipfile.ZIP_DEFLATED)
|
|
||||||
expected_length = len(metadata['ota-streaming-property-files'])
|
expected_length = len(metadata['ota-streaming-property-files'])
|
||||||
metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
|
metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
|
||||||
prelim_zip, reserve_space=False, expected_length=expected_length)
|
prelim_signing_zip, reserve_space=False, expected_length=expected_length)
|
||||||
|
common.ZipClose(prelim_signing_zip)
|
||||||
|
|
||||||
# Copy the zip entries, as we cannot update / delete entries with zipfile.
|
# Replace the METADATA entry.
|
||||||
final_signing = tempfile.NamedTemporaryFile()
|
common.ZipDelete(prelim_signing, METADATA_NAME)
|
||||||
output_zip = zipfile.ZipFile(final_signing, "w",
|
output_zip = zipfile.ZipFile(prelim_signing, 'a',
|
||||||
compression=zipfile.ZIP_DEFLATED)
|
compression=zipfile.ZIP_DEFLATED)
|
||||||
for item in prelim_zip.infolist():
|
|
||||||
if item.filename == METADATA_NAME:
|
|
||||||
continue
|
|
||||||
|
|
||||||
data = prelim_zip.read(item.filename)
|
|
||||||
out_info = copy.copy(item)
|
|
||||||
common.ZipWriteStr(output_zip, out_info, data)
|
|
||||||
|
|
||||||
# Now write the final metadata entry.
|
|
||||||
WriteMetadata(metadata, output_zip)
|
WriteMetadata(metadata, output_zip)
|
||||||
common.ZipClose(prelim_zip)
|
|
||||||
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(final_signing.name, output_file)
|
SignOutput(prelim_signing, output_file)
|
||||||
final_signing.close()
|
|
||||||
|
|
||||||
# Reopen the final signed zip to double check the streaming metadata.
|
# Reopen the final signed zip to double check the streaming metadata.
|
||||||
output_zip = zipfile.ZipFile(output_file, "r")
|
output_zip = zipfile.ZipFile(output_file, 'r')
|
||||||
actual = metadata['ota-streaming-property-files'].strip()
|
actual = metadata['ota-streaming-property-files'].strip()
|
||||||
expected = ComputeStreamingMetadata(output_zip)
|
expected = ComputeStreamingMetadata(output_zip)
|
||||||
assert actual == expected, \
|
assert actual == expected, \
|
||||||
|
|
|
@ -309,6 +309,51 @@ class CommonZipTest(unittest.TestCase):
|
||||||
finally:
|
finally:
|
||||||
os.remove(zip_file_name)
|
os.remove(zip_file_name)
|
||||||
|
|
||||||
|
def test_ZipDelete(self):
|
||||||
|
zip_file = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
|
||||||
|
output_zip = zipfile.ZipFile(zip_file.name, 'w',
|
||||||
|
compression=zipfile.ZIP_DEFLATED)
|
||||||
|
with tempfile.NamedTemporaryFile() as entry_file:
|
||||||
|
entry_file.write(os.urandom(1024))
|
||||||
|
common.ZipWrite(output_zip, entry_file.name, arcname='Test1')
|
||||||
|
common.ZipWrite(output_zip, entry_file.name, arcname='Test2')
|
||||||
|
common.ZipWrite(output_zip, entry_file.name, arcname='Test3')
|
||||||
|
common.ZipClose(output_zip)
|
||||||
|
zip_file.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
common.ZipDelete(zip_file.name, 'Test2')
|
||||||
|
with zipfile.ZipFile(zip_file.name, 'r') as check_zip:
|
||||||
|
entries = check_zip.namelist()
|
||||||
|
self.assertTrue('Test1' in entries)
|
||||||
|
self.assertFalse('Test2' in entries)
|
||||||
|
self.assertTrue('Test3' in entries)
|
||||||
|
|
||||||
|
self.assertRaises(AssertionError, common.ZipDelete, zip_file.name,
|
||||||
|
'Test2')
|
||||||
|
with zipfile.ZipFile(zip_file.name, 'r') as check_zip:
|
||||||
|
entries = check_zip.namelist()
|
||||||
|
self.assertTrue('Test1' in entries)
|
||||||
|
self.assertFalse('Test2' in entries)
|
||||||
|
self.assertTrue('Test3' in entries)
|
||||||
|
|
||||||
|
common.ZipDelete(zip_file.name, ['Test3'])
|
||||||
|
with zipfile.ZipFile(zip_file.name, 'r') as check_zip:
|
||||||
|
entries = check_zip.namelist()
|
||||||
|
self.assertTrue('Test1' in entries)
|
||||||
|
self.assertFalse('Test2' in entries)
|
||||||
|
self.assertFalse('Test3' in entries)
|
||||||
|
|
||||||
|
common.ZipDelete(zip_file.name, ['Test1', 'Test2'])
|
||||||
|
with zipfile.ZipFile(zip_file.name, 'r') as check_zip:
|
||||||
|
entries = check_zip.namelist()
|
||||||
|
self.assertFalse('Test1' in entries)
|
||||||
|
self.assertFalse('Test2' in entries)
|
||||||
|
self.assertFalse('Test3' in entries)
|
||||||
|
finally:
|
||||||
|
os.remove(zip_file.name)
|
||||||
|
|
||||||
|
|
||||||
class InstallRecoveryScriptFormatTest(unittest.TestCase):
|
class InstallRecoveryScriptFormatTest(unittest.TestCase):
|
||||||
"""Check the format of install-recovery.sh
|
"""Check the format of install-recovery.sh
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue