Based on: * system/update_engine/scripts/simulate_ota.py * system/update_engine/scripts/update_payload/applier.py Change-Id: I08085f7826e682f15602e8b628c16d054193e0bb
97 lines
3.0 KiB
Python
Executable File
97 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2020 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
"""Script to extract payload.bin from an OTA update."""
|
|
|
|
import argparse
|
|
import os
|
|
import tempfile
|
|
import zipfile
|
|
|
|
import update_payload
|
|
from update_payload import applier
|
|
|
|
def extract_ota(payload_path, list_partitions, output_dir, partitions):
|
|
"""Extract OTA payload"""
|
|
payload = update_payload.Payload(payload_path)
|
|
payload.Init()
|
|
|
|
new_parts = {}
|
|
new_part_info = {}
|
|
install_operations = []
|
|
for part in payload.manifest.partitions:
|
|
name = part.partition_name
|
|
if list_partitions:
|
|
print(name)
|
|
if partitions and name not in partitions:
|
|
continue
|
|
new_image = os.path.join(output_dir, name + ".img")
|
|
new_parts[name] = new_image
|
|
new_part_info[name] = part.new_partition_info
|
|
install_operations.append((name, part.operations))
|
|
|
|
if not list_partitions:
|
|
for name, operations in install_operations:
|
|
applier.PayloadApplier(payload)._ApplyToPartition(
|
|
operations, name, '%s_install_operations' % name, new_parts[name],
|
|
new_part_info[name])
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Extract payload.bin from OTA package")
|
|
parser.add_argument(
|
|
"payload",
|
|
help="payload.bin for the OTA package, or a zip of OTA package itself",
|
|
nargs=1
|
|
)
|
|
parser.add_argument(
|
|
"-l",
|
|
dest="list_partitions",
|
|
help="List partitions, without extracting",
|
|
action='store_true')
|
|
parser.add_argument(
|
|
"-o",
|
|
dest="output_dir",
|
|
help="Output directory to put all images, current directory by default"
|
|
)
|
|
parser.add_argument(
|
|
"-p",
|
|
dest="partitions",
|
|
help="List of partitions to extract, all by default",
|
|
nargs="*"
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
# pylint: disable=no-member
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
payload_path = args.payload[0]
|
|
if zipfile.is_zipfile(payload_path):
|
|
with zipfile.ZipFile(payload_path, "r") as zfp:
|
|
payload_entry_name = 'payload.bin'
|
|
zfp.extract(payload_entry_name, tempdir)
|
|
payload_path = os.path.join(tempdir, payload_entry_name)
|
|
if args.output_dir is None:
|
|
args.output_dir = "."
|
|
if not os.path.exists(args.output_dir):
|
|
os.makedirs(args.output_dir, exist_ok=True)
|
|
assert os.path.isdir(args.output_dir)
|
|
extract_ota(payload_path, args.list_partitions, args.output_dir, args.partitions)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|