Merge "releasetools: Support generating downgrade incremental OTAs."
am: 1284954db0
* commit '1284954db036e5c2fdf5576bd03f415b8a201078':
releasetools: Support generating downgrade incremental OTAs.
This commit is contained in:
@@ -63,6 +63,13 @@ Usage: ota_from_target_files [flags] input_target_files output_ota_package
|
|||||||
the build scripts (used for developer OTA packages which
|
the build scripts (used for developer OTA packages which
|
||||||
legitimately need to go back and forth).
|
legitimately need to go back and forth).
|
||||||
|
|
||||||
|
--downgrade
|
||||||
|
Intentionally generate an incremental OTA that updates from a newer
|
||||||
|
build to an older one (based on timestamp comparison). "post-timestamp"
|
||||||
|
will be replaced by "ota-downgrade=yes" in the metadata file. A data
|
||||||
|
wipe will always be enforced, so "ota-wipe=yes" will also be included in
|
||||||
|
the metadata file.
|
||||||
|
|
||||||
-e (--extra_script) <file>
|
-e (--extra_script) <file>
|
||||||
Insert the contents of file at the end of the update script.
|
Insert the contents of file at the end of the update script.
|
||||||
|
|
||||||
@@ -126,6 +133,7 @@ OPTIONS.prohibit_verbatim = set(("system/build.prop",))
|
|||||||
OPTIONS.patch_threshold = 0.95
|
OPTIONS.patch_threshold = 0.95
|
||||||
OPTIONS.wipe_user_data = False
|
OPTIONS.wipe_user_data = False
|
||||||
OPTIONS.omit_prereq = False
|
OPTIONS.omit_prereq = False
|
||||||
|
OPTIONS.downgrade = False
|
||||||
OPTIONS.extra_script = None
|
OPTIONS.extra_script = None
|
||||||
OPTIONS.aslr_mode = True
|
OPTIONS.aslr_mode = True
|
||||||
OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
|
OPTIONS.worker_threads = multiprocessing.cpu_count() // 2
|
||||||
@@ -698,8 +706,9 @@ reboot_now("%(bcb_dev)s", "");
|
|||||||
endif;
|
endif;
|
||||||
endif;
|
endif;
|
||||||
""" % bcb_dev)
|
""" % bcb_dev)
|
||||||
script.AddToZip(input_zip, output_zip, input_path=OPTIONS.updater_binary)
|
|
||||||
|
|
||||||
|
script.SetProgress(1)
|
||||||
|
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)
|
WriteMetadata(metadata, output_zip)
|
||||||
|
|
||||||
@@ -775,11 +784,30 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
metadata = {
|
metadata = {
|
||||||
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
|
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
|
||||||
OPTIONS.source_info_dict),
|
OPTIONS.source_info_dict),
|
||||||
"post-timestamp": GetBuildProp("ro.build.date.utc",
|
|
||||||
OPTIONS.target_info_dict),
|
|
||||||
"ota-type": "BLOCK",
|
"ota-type": "BLOCK",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict)
|
||||||
|
pre_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.source_info_dict)
|
||||||
|
is_downgrade = long(post_timestamp) < long(pre_timestamp)
|
||||||
|
|
||||||
|
if OPTIONS.downgrade:
|
||||||
|
metadata["ota-downgrade"] = "yes"
|
||||||
|
if not is_downgrade:
|
||||||
|
raise RuntimeError("--downgrade specified but no downgrade detected: "
|
||||||
|
"pre: %s, post: %s" % (pre_timestamp, post_timestamp))
|
||||||
|
else:
|
||||||
|
if is_downgrade:
|
||||||
|
# Non-fatal here to allow generating such a package which may require
|
||||||
|
# manual work to adjust the post-timestamp. A legit use case is that we
|
||||||
|
# cut a new build C (after having A and B), but want to enfore the
|
||||||
|
# update path of A -> C -> B. Specifying --downgrade may not help since
|
||||||
|
# that would enforce a data wipe for C -> B update.
|
||||||
|
print("\nWARNING: downgrade detected: pre: %s, post: %s.\n"
|
||||||
|
"The package may not be deployed properly. "
|
||||||
|
"Try --downgrade?\n" % (pre_timestamp, post_timestamp))
|
||||||
|
metadata["post-timestamp"] = post_timestamp
|
||||||
|
|
||||||
device_specific = common.DeviceSpecificParams(
|
device_specific = common.DeviceSpecificParams(
|
||||||
source_zip=source_zip,
|
source_zip=source_zip,
|
||||||
source_version=source_version,
|
source_version=source_version,
|
||||||
@@ -1009,6 +1037,7 @@ else
|
|||||||
if OPTIONS.wipe_user_data:
|
if OPTIONS.wipe_user_data:
|
||||||
script.Print("Erasing user data...")
|
script.Print("Erasing user data...")
|
||||||
script.FormatPartition("/data")
|
script.FormatPartition("/data")
|
||||||
|
metadata["ota-wipe"] = "yes"
|
||||||
|
|
||||||
if OPTIONS.two_step:
|
if OPTIONS.two_step:
|
||||||
script.AppendExtra("""
|
script.AppendExtra("""
|
||||||
@@ -1392,11 +1421,30 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip):
|
|||||||
metadata = {
|
metadata = {
|
||||||
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
|
"pre-device": GetOemProperty("ro.product.device", oem_props, oem_dict,
|
||||||
OPTIONS.source_info_dict),
|
OPTIONS.source_info_dict),
|
||||||
"post-timestamp": GetBuildProp("ro.build.date.utc",
|
|
||||||
OPTIONS.target_info_dict),
|
|
||||||
"ota-type": "FILE",
|
"ota-type": "FILE",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.target_info_dict)
|
||||||
|
pre_timestamp = GetBuildProp("ro.build.date.utc", OPTIONS.source_info_dict)
|
||||||
|
is_downgrade = long(post_timestamp) < long(pre_timestamp)
|
||||||
|
|
||||||
|
if OPTIONS.downgrade:
|
||||||
|
metadata["ota-downgrade"] = "yes"
|
||||||
|
if not is_downgrade:
|
||||||
|
raise RuntimeError("--downgrade specified but no downgrade detected: "
|
||||||
|
"pre: %s, post: %s" % (pre_timestamp, post_timestamp))
|
||||||
|
else:
|
||||||
|
if is_downgrade:
|
||||||
|
# Non-fatal here to allow generating such a package which may require
|
||||||
|
# manual work to adjust the post-timestamp. A legit use case is that we
|
||||||
|
# cut a new build C (after having A and B), but want to enfore the
|
||||||
|
# update path of A -> C -> B. Specifying --downgrade may not help since
|
||||||
|
# that would enforce a data wipe for C -> B update.
|
||||||
|
print("\nWARNING: downgrade detected: pre: %s, post: %s.\n"
|
||||||
|
"The package may not be deployed properly. "
|
||||||
|
"Try --downgrade?\n" % (pre_timestamp, post_timestamp))
|
||||||
|
metadata["post-timestamp"] = post_timestamp
|
||||||
|
|
||||||
device_specific = common.DeviceSpecificParams(
|
device_specific = common.DeviceSpecificParams(
|
||||||
source_zip=source_zip,
|
source_zip=source_zip,
|
||||||
source_version=source_version,
|
source_version=source_version,
|
||||||
@@ -1725,6 +1773,7 @@ else
|
|||||||
if OPTIONS.wipe_user_data:
|
if OPTIONS.wipe_user_data:
|
||||||
script.Print("Erasing user data...")
|
script.Print("Erasing user data...")
|
||||||
script.FormatPartition("/data")
|
script.FormatPartition("/data")
|
||||||
|
metadata["ota-wipe"] = "yes"
|
||||||
|
|
||||||
if OPTIONS.two_step:
|
if OPTIONS.two_step:
|
||||||
script.AppendExtra("""
|
script.AppendExtra("""
|
||||||
@@ -1767,6 +1816,9 @@ def main(argv):
|
|||||||
OPTIONS.wipe_user_data = True
|
OPTIONS.wipe_user_data = True
|
||||||
elif o in ("-n", "--no_prereq"):
|
elif o in ("-n", "--no_prereq"):
|
||||||
OPTIONS.omit_prereq = True
|
OPTIONS.omit_prereq = True
|
||||||
|
elif o == "--downgrade":
|
||||||
|
OPTIONS.downgrade = True
|
||||||
|
OPTIONS.wipe_user_data = True
|
||||||
elif o in ("-o", "--oem_settings"):
|
elif o in ("-o", "--oem_settings"):
|
||||||
OPTIONS.oem_source = a
|
OPTIONS.oem_source = a
|
||||||
elif o in ("-e", "--extra_script"):
|
elif o in ("-e", "--extra_script"):
|
||||||
@@ -1818,6 +1870,7 @@ def main(argv):
|
|||||||
"full_bootloader",
|
"full_bootloader",
|
||||||
"wipe_user_data",
|
"wipe_user_data",
|
||||||
"no_prereq",
|
"no_prereq",
|
||||||
|
"downgrade",
|
||||||
"extra_script=",
|
"extra_script=",
|
||||||
"worker_threads=",
|
"worker_threads=",
|
||||||
"aslr_mode=",
|
"aslr_mode=",
|
||||||
@@ -1837,6 +1890,18 @@ def main(argv):
|
|||||||
common.Usage(__doc__)
|
common.Usage(__doc__)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if OPTIONS.downgrade:
|
||||||
|
# Sanity check to enforce a data wipe.
|
||||||
|
if not OPTIONS.wipe_user_data:
|
||||||
|
raise ValueError("Cannot downgrade without a data wipe")
|
||||||
|
|
||||||
|
# We should only allow downgrading incrementals (as opposed to full).
|
||||||
|
# Otherwise the device may go back from arbitrary build with this full
|
||||||
|
# OTA package.
|
||||||
|
if OPTIONS.incremental_source is None:
|
||||||
|
raise ValueError("Cannot generate downgradable full OTAs - consider"
|
||||||
|
"using --omit_prereq?")
|
||||||
|
|
||||||
# Load the dict file from the zip directly to have a peek at the OTA type.
|
# Load the dict file from the zip directly to have a peek at the OTA type.
|
||||||
# For packages using A/B update, unzipping is not needed.
|
# For packages using A/B update, unzipping is not needed.
|
||||||
input_zip = zipfile.ZipFile(args[0], "r")
|
input_zip = zipfile.ZipFile(args[0], "r")
|
||||||
|
Reference in New Issue
Block a user