2014-07-31 20:06:30 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright (C) 2014 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.
|
|
|
|
|
|
|
|
"""
|
|
|
|
Given a target-files zipfile that does not contain images (ie, does
|
|
|
|
not have an IMAGES/ top-level subdirectory), produce the images and
|
|
|
|
add them to the zipfile.
|
|
|
|
|
2016-08-04 04:21:52 +02:00
|
|
|
Usage: add_img_to_target_files [flag] target_files
|
|
|
|
|
|
|
|
-a (--add_missing)
|
|
|
|
Build and add missing images to "IMAGES/". If this option is
|
|
|
|
not specified, this script will simply exit when "IMAGES/"
|
|
|
|
directory exists in the target file.
|
|
|
|
|
|
|
|
-r (--rebuild_recovery)
|
|
|
|
Rebuild the recovery patch and write it to the system image. Only
|
|
|
|
meaningful when system image needs to be rebuilt.
|
|
|
|
|
|
|
|
--replace_verity_private_key
|
|
|
|
Replace the private key used for verity signing. (same as the option
|
|
|
|
in sign_target_files_apks)
|
|
|
|
|
|
|
|
--replace_verity_public_key
|
|
|
|
Replace the certificate (public key) used for verity verification. (same
|
|
|
|
as the option in sign_target_files_apks)
|
|
|
|
|
|
|
|
--is_signing
|
|
|
|
Skip building & adding the images for "userdata" and "cache" if we
|
|
|
|
are signing the target files.
|
2014-07-31 20:06:30 +02:00
|
|
|
"""
|
|
|
|
|
2017-01-10 19:47:58 +01:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2015-10-01 01:01:14 +02:00
|
|
|
import datetime
|
2017-09-28 02:17:43 +02:00
|
|
|
import hashlib
|
2014-07-31 20:06:30 +02:00
|
|
|
import os
|
2016-01-29 22:59:17 +01:00
|
|
|
import shlex
|
2015-06-25 22:56:53 +02:00
|
|
|
import shutil
|
2016-01-29 22:59:17 +01:00
|
|
|
import subprocess
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
import sys
|
2014-07-31 20:06:30 +02:00
|
|
|
import tempfile
|
2017-09-23 00:45:33 +02:00
|
|
|
import uuid
|
2014-07-31 20:06:30 +02:00
|
|
|
import zipfile
|
|
|
|
|
|
|
|
import build_image
|
|
|
|
import common
|
2017-01-20 02:39:30 +01:00
|
|
|
import rangelib
|
2016-03-08 01:31:19 +01:00
|
|
|
import sparse_img
|
2014-07-31 20:06:30 +02:00
|
|
|
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
if sys.hexversion < 0x02070000:
|
|
|
|
print("Python 2.7 or newer is required.", file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
OPTIONS = common.OPTIONS
|
|
|
|
|
2014-11-14 06:41:08 +01:00
|
|
|
OPTIONS.add_missing = False
|
|
|
|
OPTIONS.rebuild_recovery = False
|
2017-06-10 01:58:03 +02:00
|
|
|
OPTIONS.replace_updated_files_list = []
|
2015-09-17 06:20:30 +02:00
|
|
|
OPTIONS.replace_verity_public_key = False
|
|
|
|
OPTIONS.replace_verity_private_key = False
|
2016-08-04 04:21:52 +02:00
|
|
|
OPTIONS.is_signing = False
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
|
|
|
|
class OutputFile(object):
|
|
|
|
def __init__(self, output_zip, input_dir, prefix, name):
|
|
|
|
self._output_zip = output_zip
|
|
|
|
self.input_name = os.path.join(input_dir, prefix, name)
|
|
|
|
|
|
|
|
if self._output_zip:
|
|
|
|
self._zip_name = os.path.join(prefix, name)
|
|
|
|
|
|
|
|
root, suffix = os.path.splitext(name)
|
|
|
|
self.name = common.MakeTempFile(prefix=root + '-', suffix=suffix)
|
|
|
|
else:
|
|
|
|
self.name = self.input_name
|
|
|
|
|
|
|
|
def Write(self):
|
|
|
|
if self._output_zip:
|
|
|
|
common.ZipWrite(self._output_zip, self.name, self._zip_name)
|
|
|
|
|
|
|
|
|
2016-03-08 01:31:19 +01:00
|
|
|
def GetCareMap(which, imgname):
|
|
|
|
"""Generate care_map of system (or vendor) partition"""
|
|
|
|
|
|
|
|
assert which in ("system", "vendor")
|
|
|
|
|
|
|
|
simg = sparse_img.SparseImage(imgname)
|
2017-06-10 01:58:03 +02:00
|
|
|
care_map_list = [which]
|
2017-01-20 02:39:30 +01:00
|
|
|
|
|
|
|
care_map_ranges = simg.care_map
|
|
|
|
key = which + "_adjusted_partition_size"
|
|
|
|
adjusted_blocks = OPTIONS.info_dict.get(key)
|
|
|
|
if adjusted_blocks:
|
|
|
|
assert adjusted_blocks > 0, "blocks should be positive for " + which
|
|
|
|
care_map_ranges = care_map_ranges.intersect(rangelib.RangeSet(
|
|
|
|
"0-%d" % (adjusted_blocks,)))
|
|
|
|
|
|
|
|
care_map_list.append(care_map_ranges.to_string_raw())
|
2016-03-08 01:31:19 +01:00
|
|
|
return care_map_list
|
|
|
|
|
|
|
|
|
2014-11-14 06:41:08 +01:00
|
|
|
def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
|
2014-07-31 20:06:30 +02:00
|
|
|
"""Turn the contents of SYSTEM into a system image and store it in
|
2016-01-29 22:59:17 +01:00
|
|
|
output_zip. Returns the name of the system image file."""
|
2014-11-14 06:41:08 +01:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system.img")
|
|
|
|
if os.path.exists(img.input_name):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("system.img already exists in %s, no need to rebuild..." % (prefix,))
|
2017-03-06 04:51:56 +01:00
|
|
|
return img.input_name
|
2014-11-14 06:41:08 +01:00
|
|
|
|
|
|
|
def output_sink(fn, data):
|
2015-03-24 03:13:21 +01:00
|
|
|
ofile = open(os.path.join(OPTIONS.input_tmp, "SYSTEM", fn), "w")
|
|
|
|
ofile.write(data)
|
|
|
|
ofile.close()
|
2014-11-14 06:41:08 +01:00
|
|
|
|
2017-05-26 02:38:53 +02:00
|
|
|
arc_name = "SYSTEM/" + fn
|
|
|
|
if arc_name in output_zip.namelist():
|
2017-06-10 01:58:03 +02:00
|
|
|
OPTIONS.replace_updated_files_list.append(arc_name)
|
2017-05-26 02:38:53 +02:00
|
|
|
else:
|
|
|
|
common.ZipWrite(output_zip, ofile.name, arc_name)
|
|
|
|
|
2014-11-14 06:41:08 +01:00
|
|
|
if OPTIONS.rebuild_recovery:
|
2017-01-10 19:47:58 +01:00
|
|
|
print("Building new recovery patch")
|
2015-03-24 03:13:21 +01:00
|
|
|
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
|
|
|
|
boot_img, info_dict=OPTIONS.info_dict)
|
2014-11-14 06:41:08 +01:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
block_list = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system.map")
|
|
|
|
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system", img,
|
|
|
|
block_list=block_list)
|
2016-01-29 22:59:17 +01:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
return img.name
|
2014-08-26 22:10:25 +02:00
|
|
|
|
|
|
|
|
2016-06-16 23:47:10 +02:00
|
|
|
def AddSystemOther(output_zip, prefix="IMAGES/"):
|
|
|
|
"""Turn the contents of SYSTEM_OTHER into a system_other image
|
|
|
|
and store it in output_zip."""
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "system_other.img")
|
|
|
|
if os.path.exists(img.input_name):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("system_other.img already exists in %s, no need to rebuild..." % (
|
|
|
|
prefix,))
|
2016-06-16 23:47:10 +02:00
|
|
|
return
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system_other", img)
|
2016-06-16 23:47:10 +02:00
|
|
|
|
|
|
|
|
2014-08-26 22:10:25 +02:00
|
|
|
def AddVendor(output_zip, prefix="IMAGES/"):
|
|
|
|
"""Turn the contents of VENDOR into a vendor image and store in it
|
|
|
|
output_zip."""
|
2014-11-14 06:41:08 +01:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vendor.img")
|
|
|
|
if os.path.exists(img.input_name):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("vendor.img already exists in %s, no need to rebuild..." % (prefix,))
|
2017-03-06 04:51:56 +01:00
|
|
|
return img.input_name
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
block_list = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vendor.map")
|
|
|
|
CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "vendor", img,
|
|
|
|
block_list=block_list)
|
|
|
|
return img.name
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2017-05-13 02:50:46 +02:00
|
|
|
|
2017-05-31 06:46:33 +02:00
|
|
|
def AddDtbo(output_zip, prefix="IMAGES/"):
|
|
|
|
"""Adds the DTBO image.
|
|
|
|
|
|
|
|
Uses the image under prefix if it already exists. Otherwise looks for the
|
|
|
|
image under PREBUILT_IMAGES/, signs it as needed, and returns the image name.
|
|
|
|
"""
|
|
|
|
|
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "dtbo.img")
|
|
|
|
if os.path.exists(img.input_name):
|
|
|
|
print("dtbo.img already exists in %s, no need to rebuild..." % (prefix,))
|
|
|
|
return img.input_name
|
|
|
|
|
|
|
|
dtbo_prebuilt_path = os.path.join(
|
|
|
|
OPTIONS.input_tmp, "PREBUILT_IMAGES", "dtbo.img")
|
|
|
|
assert os.path.exists(dtbo_prebuilt_path)
|
|
|
|
shutil.copy(dtbo_prebuilt_path, img.name)
|
|
|
|
|
|
|
|
# AVB-sign the image as needed.
|
2017-05-26 12:30:04 +02:00
|
|
|
if OPTIONS.info_dict.get("avb_enable") == "true":
|
2017-05-31 06:46:33 +02:00
|
|
|
avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
|
2017-05-24 08:06:55 +02:00
|
|
|
part_size = OPTIONS.info_dict["dtbo_size"]
|
2017-05-31 06:46:33 +02:00
|
|
|
# The AVB hash footer will be replaced if already present.
|
|
|
|
cmd = [avbtool, "add_hash_footer", "--image", img.name,
|
|
|
|
"--partition_size", str(part_size), "--partition_name", "dtbo"]
|
2017-05-26 12:30:04 +02:00
|
|
|
common.AppendAVBSigningArgs(cmd, "dtbo")
|
|
|
|
args = OPTIONS.info_dict.get("avb_dtbo_add_hash_footer_args")
|
2017-05-31 06:46:33 +02:00
|
|
|
if args and args.strip():
|
|
|
|
cmd.extend(shlex.split(args))
|
|
|
|
p = common.Run(cmd, stdout=subprocess.PIPE)
|
|
|
|
p.communicate()
|
|
|
|
assert p.returncode == 0, \
|
|
|
|
"avbtool add_hash_footer of %s failed" % (img.name,)
|
|
|
|
|
|
|
|
img.Write()
|
|
|
|
return img.name
|
|
|
|
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("creating " + what + ".img...")
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
|
|
|
|
fstab = info_dict["fstab"]
|
2016-03-08 01:31:19 +01:00
|
|
|
mount_point = "/" + what
|
|
|
|
if fstab and mount_point in fstab:
|
|
|
|
image_props["fs_type"] = fstab[mount_point].fs_type
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2015-10-01 01:01:14 +02:00
|
|
|
# Use a fixed timestamp (01/01/2009) when packaging the image.
|
|
|
|
# Bug: 24377993
|
|
|
|
epoch = datetime.datetime.fromtimestamp(0)
|
|
|
|
timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
|
|
|
|
image_props["timestamp"] = int(timestamp)
|
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
if what == "system":
|
|
|
|
fs_config_prefix = ""
|
|
|
|
else:
|
|
|
|
fs_config_prefix = what + "_"
|
|
|
|
|
|
|
|
fs_config = os.path.join(
|
|
|
|
input_dir, "META/" + fs_config_prefix + "filesystem_config.txt")
|
2015-03-24 03:13:21 +01:00
|
|
|
if not os.path.exists(fs_config):
|
|
|
|
fs_config = None
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2015-03-25 03:07:40 +01:00
|
|
|
# Override values loaded from info_dict.
|
|
|
|
if fs_config:
|
|
|
|
image_props["fs_config"] = fs_config
|
|
|
|
if block_list:
|
2017-03-06 04:51:56 +01:00
|
|
|
image_props["block_list"] = block_list.name
|
2015-03-25 03:07:40 +01:00
|
|
|
|
2017-09-23 00:45:33 +02:00
|
|
|
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
|
|
|
|
# build fingerprint).
|
|
|
|
uuid_seed = what + "-"
|
|
|
|
if "build.prop" in info_dict:
|
|
|
|
build_prop = info_dict["build.prop"]
|
|
|
|
if "ro.build.fingerprint" in build_prop:
|
|
|
|
uuid_seed += build_prop["ro.build.fingerprint"]
|
|
|
|
elif "ro.build.thumbprint" in build_prop:
|
|
|
|
uuid_seed += build_prop["ro.build.thumbprint"]
|
|
|
|
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
|
|
|
|
hash_seed = "hash_seed-" + uuid_seed
|
|
|
|
image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
|
|
|
|
|
2017-05-24 08:49:03 +02:00
|
|
|
succ = build_image.BuildImage(os.path.join(input_dir, what.upper()),
|
2017-03-06 04:51:56 +01:00
|
|
|
image_props, output_file.name)
|
2014-07-31 20:06:30 +02:00
|
|
|
assert succ, "build " + what + ".img image failed"
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
output_file.Write()
|
|
|
|
if block_list:
|
|
|
|
block_list.Write()
|
|
|
|
|
2017-06-01 20:32:32 +02:00
|
|
|
# Set the 'adjusted_partition_size' that excludes the verity blocks of the
|
|
|
|
# given image. When avb is enabled, this size is the max image size returned
|
|
|
|
# by the avb tool.
|
2017-01-20 02:39:30 +01:00
|
|
|
is_verity_partition = "verity_block_device" in image_props
|
2017-06-01 20:32:32 +02:00
|
|
|
verity_supported = (image_props.get("verity") == "true" or
|
2017-05-26 12:30:04 +02:00
|
|
|
image_props.get("avb_enable") == "true")
|
2017-06-01 20:32:32 +02:00
|
|
|
is_avb_enable = image_props.get("avb_hashtree_enable") == "true"
|
|
|
|
if verity_supported and (is_verity_partition or is_avb_enable):
|
2017-01-20 02:39:30 +01:00
|
|
|
adjusted_blocks_value = image_props.get("partition_size")
|
|
|
|
if adjusted_blocks_value:
|
|
|
|
adjusted_blocks_key = what + "_adjusted_partition_size"
|
|
|
|
info_dict[adjusted_blocks_key] = int(adjusted_blocks_value)/4096 - 1
|
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
def AddUserdata(output_zip, prefix="IMAGES/"):
|
2015-06-25 22:56:53 +02:00
|
|
|
"""Create a userdata image and store it in output_zip.
|
|
|
|
|
|
|
|
In most case we just create and store an empty userdata.img;
|
|
|
|
But the invoker can also request to create userdata.img with real
|
|
|
|
data from the target files, by setting "userdata_img_with_data=true"
|
|
|
|
in OPTIONS.info_dict.
|
|
|
|
"""
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "userdata.img")
|
|
|
|
if os.path.exists(img.input_name):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("userdata.img already exists in %s, no need to rebuild..." % (
|
|
|
|
prefix,))
|
2014-11-14 06:41:08 +01:00
|
|
|
return
|
|
|
|
|
2016-06-16 02:04:54 +02:00
|
|
|
# Skip userdata.img if no size.
|
2015-07-09 20:51:16 +02:00
|
|
|
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, "data")
|
2016-06-16 02:04:54 +02:00
|
|
|
if not image_props.get("partition_size"):
|
2014-07-31 20:06:30 +02:00
|
|
|
return
|
|
|
|
|
2017-01-10 19:47:58 +01:00
|
|
|
print("creating userdata.img...")
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2015-10-01 01:01:14 +02:00
|
|
|
# Use a fixed timestamp (01/01/2009) when packaging the image.
|
|
|
|
# Bug: 24377993
|
|
|
|
epoch = datetime.datetime.fromtimestamp(0)
|
|
|
|
timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
|
|
|
|
image_props["timestamp"] = int(timestamp)
|
|
|
|
|
2017-05-24 08:49:03 +02:00
|
|
|
if OPTIONS.info_dict.get("userdata_img_with_data") == "true":
|
|
|
|
user_dir = os.path.join(OPTIONS.input_tmp, "DATA")
|
2015-06-25 22:56:53 +02:00
|
|
|
else:
|
2017-05-24 08:49:03 +02:00
|
|
|
user_dir = tempfile.mkdtemp()
|
|
|
|
OPTIONS.tempfiles.append(user_dir)
|
2015-06-25 22:56:53 +02:00
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
fstab = OPTIONS.info_dict["fstab"]
|
|
|
|
if fstab:
|
2015-03-24 03:13:21 +01:00
|
|
|
image_props["fs_type"] = fstab["/data"].fs_type
|
2014-07-31 20:06:30 +02:00
|
|
|
succ = build_image.BuildImage(user_dir, image_props, img.name)
|
|
|
|
assert succ, "build userdata.img image failed"
|
|
|
|
|
|
|
|
common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
|
2017-03-06 04:51:56 +01:00
|
|
|
img.Write()
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
|
2017-05-26 12:30:04 +02:00
|
|
|
def AppendVBMetaArgsForPartition(cmd, partition, img_path, public_key_dir):
|
|
|
|
if not img_path:
|
|
|
|
return
|
|
|
|
|
|
|
|
# Check if chain partition is used.
|
|
|
|
key_path = OPTIONS.info_dict.get("avb_" + partition + "_key_path")
|
|
|
|
if key_path:
|
|
|
|
# extract public key in AVB format to be included in vbmeta.img
|
|
|
|
avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
|
|
|
|
public_key_path = os.path.join(public_key_dir, "%s.avbpubkey" % partition)
|
|
|
|
p = common.Run([avbtool, "extract_public_key", "--key", key_path,
|
|
|
|
"--output", public_key_path],
|
|
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
p.communicate()
|
|
|
|
assert p.returncode == 0, \
|
|
|
|
"avbtool extract_public_key fail for partition: %r" % partition
|
|
|
|
|
|
|
|
rollback_index_location = OPTIONS.info_dict[
|
|
|
|
"avb_" + partition + "_rollback_index_location"]
|
|
|
|
cmd.extend(["--chain_partition", "%s:%s:%s" % (
|
|
|
|
partition, rollback_index_location, public_key_path)])
|
|
|
|
else:
|
|
|
|
cmd.extend(["--include_descriptors_from_image", img_path])
|
|
|
|
|
|
|
|
|
2017-07-12 02:27:55 +02:00
|
|
|
def AddVBMeta(output_zip, partitions, prefix="IMAGES/"):
|
|
|
|
"""Creates a VBMeta image and store it in output_zip.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
output_zip: The output zip file, which needs to be already open.
|
|
|
|
partitions: A dict that's keyed by partition names with image paths as
|
|
|
|
values. Only valid partition names are accepted, which include 'boot',
|
|
|
|
'recovery', 'system', 'vendor', 'dtbo'.
|
|
|
|
"""
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "vbmeta.img")
|
2017-07-12 02:27:55 +02:00
|
|
|
if os.path.exists(img.input_name):
|
|
|
|
print("vbmeta.img already exists in %s; not rebuilding..." % (prefix,))
|
|
|
|
return img.input_name
|
|
|
|
|
2017-05-31 06:46:33 +02:00
|
|
|
avbtool = os.getenv('AVBTOOL') or OPTIONS.info_dict["avb_avbtool"]
|
2017-05-26 12:30:04 +02:00
|
|
|
cmd = [avbtool, "make_vbmeta_image", "--output", img.name]
|
|
|
|
common.AppendAVBSigningArgs(cmd, "vbmeta")
|
|
|
|
|
|
|
|
public_key_dir = tempfile.mkdtemp(prefix="avbpubkey-")
|
|
|
|
OPTIONS.tempfiles.append(public_key_dir)
|
|
|
|
|
2017-07-12 02:27:55 +02:00
|
|
|
for partition, path in partitions.items():
|
|
|
|
assert partition in common.AVB_PARTITIONS, 'Unknown partition: %s' % (
|
|
|
|
partition,)
|
|
|
|
assert os.path.exists(path), 'Failed to find %s for partition %s' % (
|
|
|
|
path, partition)
|
|
|
|
AppendVBMetaArgsForPartition(cmd, partition, path, public_key_dir)
|
2017-05-26 12:30:04 +02:00
|
|
|
|
|
|
|
args = OPTIONS.info_dict.get("avb_vbmeta_args")
|
Update for new Android Verified Boot (AVB).
This updates the build system for the new Android Verified Boot
codebase. As this is based on Brillo Verified Boot, this change replaces
the existing BVB support.
Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable
BOARD_AVB_ENABLE := true
This will make the build system create vbmeta.img which will contain a
hash descriptor for boot.img, a hashtree descriptor for system.img, a
kernel-cmdline descriptor for setting up dm-verity for system.img and
append a hash-tree to system.img.
Additionally, the descriptors are left in boot.img and system.img so a
third party can create their own vbmeta.img file linking - using the
option --chain_partition - to these images. If this is not needed
footers can be erased using the 'avbtool erase_footer' command. It's
also harmless to just leave them in the images.
By default, the algorithm SHA256_RSA4096 is used with a test key from
the AVB source directory. This can be overriden by the
BOARD_AVB_ALGORITHM and BOARD_AVB_KEY_PATH variables to use e.g. a
4096-bit RSA key and SHA-512:
BOARD_AVB_ALGORITHM := SHA512_RSA4096
BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
To prevent rollback attacks, the rollback index should be increased on a
regular basis. The rollback index can be set with the
BOARD_AVB_ROLLBACK_INDEX variable:
BOARD_AVB_ROLLBACK_INDEX := 5
If this is not set, the rollback index defaults to 0.
The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify
additional options passed to 'avbtool make_vbmeta_image'. Typical
options to be used here include '--prop', '--prop_from_file', and
'--chain_partition'.
The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to
specify additional options passed to 'avbtool add_hash_footer' for
boot.img. Typical options to be used here include '--hash_algorithm' and
'--salt'.
The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used
to specify additional options passed to 'avbtool add_hashtree_footer'
for systems.img. Typical options to be used here include
'--hash_algorithm', '--salt', and '--block_size'.
BUG=31264226
TEST=Manually tested on edison-eng by inspecting {boot, system,
vbmeta}.img in out/ directory as well as their counterparts in
the IMAGES/ directory of edision-target_files-eng.zeuthen.zip
Merged-In: Ic9a61cfc65c148b12996e57f04da5432eef6b982
Change-Id: I97042655bca15e7eac899f12c5bada2f6184d307
2016-09-15 19:43:54 +02:00
|
|
|
if args and args.strip():
|
2017-07-21 08:51:16 +02:00
|
|
|
split_args = shlex.split(args)
|
|
|
|
for index, arg in enumerate(split_args[:-1]):
|
|
|
|
# Sanity check that the image file exists. Some images might be defined
|
|
|
|
# as a path relative to source tree, which may not be available at the
|
|
|
|
# same location when running this script (we have the input target_files
|
|
|
|
# zip only). For such cases, we additionally scan other locations (e.g.
|
|
|
|
# IMAGES/, RADIO/, etc) before bailing out.
|
|
|
|
if arg == '--include_descriptors_from_image':
|
|
|
|
image_path = split_args[index + 1]
|
|
|
|
if os.path.exists(image_path):
|
|
|
|
continue
|
|
|
|
found = False
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
for dir_name in ['IMAGES', 'RADIO', 'VENDOR_IMAGES', 'PREBUILT_IMAGES']:
|
2017-07-21 08:51:16 +02:00
|
|
|
alt_path = os.path.join(
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
OPTIONS.input_tmp, dir_name, os.path.basename(image_path))
|
2017-07-21 08:51:16 +02:00
|
|
|
if os.path.exists(alt_path):
|
|
|
|
split_args[index + 1] = alt_path
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
assert found, 'failed to find %s' % (image_path,)
|
|
|
|
cmd.extend(split_args)
|
2017-05-26 12:30:04 +02:00
|
|
|
|
Update for new Android Verified Boot (AVB).
This updates the build system for the new Android Verified Boot
codebase. As this is based on Brillo Verified Boot, this change replaces
the existing BVB support.
Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable
BOARD_AVB_ENABLE := true
This will make the build system create vbmeta.img which will contain a
hash descriptor for boot.img, a hashtree descriptor for system.img, a
kernel-cmdline descriptor for setting up dm-verity for system.img and
append a hash-tree to system.img.
Additionally, the descriptors are left in boot.img and system.img so a
third party can create their own vbmeta.img file linking - using the
option --chain_partition - to these images. If this is not needed
footers can be erased using the 'avbtool erase_footer' command. It's
also harmless to just leave them in the images.
By default, the algorithm SHA256_RSA4096 is used with a test key from
the AVB source directory. This can be overriden by the
BOARD_AVB_ALGORITHM and BOARD_AVB_KEY_PATH variables to use e.g. a
4096-bit RSA key and SHA-512:
BOARD_AVB_ALGORITHM := SHA512_RSA4096
BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
To prevent rollback attacks, the rollback index should be increased on a
regular basis. The rollback index can be set with the
BOARD_AVB_ROLLBACK_INDEX variable:
BOARD_AVB_ROLLBACK_INDEX := 5
If this is not set, the rollback index defaults to 0.
The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify
additional options passed to 'avbtool make_vbmeta_image'. Typical
options to be used here include '--prop', '--prop_from_file', and
'--chain_partition'.
The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to
specify additional options passed to 'avbtool add_hash_footer' for
boot.img. Typical options to be used here include '--hash_algorithm' and
'--salt'.
The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used
to specify additional options passed to 'avbtool add_hashtree_footer'
for systems.img. Typical options to be used here include
'--hash_algorithm', '--salt', and '--block_size'.
BUG=31264226
TEST=Manually tested on edison-eng by inspecting {boot, system,
vbmeta}.img in out/ directory as well as their counterparts in
the IMAGES/ directory of edision-target_files-eng.zeuthen.zip
Merged-In: Ic9a61cfc65c148b12996e57f04da5432eef6b982
Change-Id: I97042655bca15e7eac899f12c5bada2f6184d307
2016-09-15 19:43:54 +02:00
|
|
|
p = common.Run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
p.communicate()
|
|
|
|
assert p.returncode == 0, "avbtool make_vbmeta_image failed"
|
2017-03-06 04:51:56 +01:00
|
|
|
img.Write()
|
Update for new Android Verified Boot (AVB).
This updates the build system for the new Android Verified Boot
codebase. As this is based on Brillo Verified Boot, this change replaces
the existing BVB support.
Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable
BOARD_AVB_ENABLE := true
This will make the build system create vbmeta.img which will contain a
hash descriptor for boot.img, a hashtree descriptor for system.img, a
kernel-cmdline descriptor for setting up dm-verity for system.img and
append a hash-tree to system.img.
Additionally, the descriptors are left in boot.img and system.img so a
third party can create their own vbmeta.img file linking - using the
option --chain_partition - to these images. If this is not needed
footers can be erased using the 'avbtool erase_footer' command. It's
also harmless to just leave them in the images.
By default, the algorithm SHA256_RSA4096 is used with a test key from
the AVB source directory. This can be overriden by the
BOARD_AVB_ALGORITHM and BOARD_AVB_KEY_PATH variables to use e.g. a
4096-bit RSA key and SHA-512:
BOARD_AVB_ALGORITHM := SHA512_RSA4096
BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
To prevent rollback attacks, the rollback index should be increased on a
regular basis. The rollback index can be set with the
BOARD_AVB_ROLLBACK_INDEX variable:
BOARD_AVB_ROLLBACK_INDEX := 5
If this is not set, the rollback index defaults to 0.
The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify
additional options passed to 'avbtool make_vbmeta_image'. Typical
options to be used here include '--prop', '--prop_from_file', and
'--chain_partition'.
The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to
specify additional options passed to 'avbtool add_hash_footer' for
boot.img. Typical options to be used here include '--hash_algorithm' and
'--salt'.
The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used
to specify additional options passed to 'avbtool add_hashtree_footer'
for systems.img. Typical options to be used here include
'--hash_algorithm', '--salt', and '--block_size'.
BUG=31264226
TEST=Manually tested on edison-eng by inspecting {boot, system,
vbmeta}.img in out/ directory as well as their counterparts in
the IMAGES/ directory of edision-target_files-eng.zeuthen.zip
Merged-In: Ic9a61cfc65c148b12996e57f04da5432eef6b982
Change-Id: I97042655bca15e7eac899f12c5bada2f6184d307
2016-09-15 19:43:54 +02:00
|
|
|
|
|
|
|
|
2016-04-08 21:08:03 +02:00
|
|
|
def AddPartitionTable(output_zip, prefix="IMAGES/"):
|
|
|
|
"""Create a partition table image and store it in output_zip."""
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "partition-table.img")
|
|
|
|
bpt = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "partition-table.bpt")
|
2016-04-08 21:08:03 +02:00
|
|
|
|
|
|
|
# use BPTTOOL from environ, or "bpttool" if empty or not set.
|
|
|
|
bpttool = os.getenv("BPTTOOL") or "bpttool"
|
2017-03-06 04:51:56 +01:00
|
|
|
cmd = [bpttool, "make_table", "--output_json", bpt.name,
|
|
|
|
"--output_gpt", img.name]
|
2016-04-08 21:08:03 +02:00
|
|
|
input_files_str = OPTIONS.info_dict["board_bpt_input_files"]
|
|
|
|
input_files = input_files_str.split(" ")
|
|
|
|
for i in input_files:
|
|
|
|
cmd.extend(["--input", i])
|
|
|
|
disk_size = OPTIONS.info_dict.get("board_bpt_disk_size")
|
|
|
|
if disk_size:
|
|
|
|
cmd.extend(["--disk_size", disk_size])
|
|
|
|
args = OPTIONS.info_dict.get("board_bpt_make_table_args")
|
|
|
|
if args:
|
|
|
|
cmd.extend(shlex.split(args))
|
|
|
|
|
|
|
|
p = common.Run(cmd, stdout=subprocess.PIPE)
|
|
|
|
p.communicate()
|
|
|
|
assert p.returncode == 0, "bpttool make_table failed"
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img.Write()
|
|
|
|
bpt.Write()
|
2016-04-08 21:08:03 +02:00
|
|
|
|
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
def AddCache(output_zip, prefix="IMAGES/"):
|
|
|
|
"""Create an empty cache image and store it in output_zip."""
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
img = OutputFile(output_zip, OPTIONS.input_tmp, prefix, "cache.img")
|
|
|
|
if os.path.exists(img.input_name):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("cache.img already exists in %s, no need to rebuild..." % (prefix,))
|
2014-11-14 06:41:08 +01:00
|
|
|
return
|
|
|
|
|
2015-07-09 20:51:16 +02:00
|
|
|
image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict, "cache")
|
2014-07-31 20:06:30 +02:00
|
|
|
# The build system has to explicitly request for cache.img.
|
|
|
|
if "fs_type" not in image_props:
|
|
|
|
return
|
|
|
|
|
2017-01-10 19:47:58 +01:00
|
|
|
print("creating cache.img...")
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2015-10-01 01:01:14 +02:00
|
|
|
# Use a fixed timestamp (01/01/2009) when packaging the image.
|
|
|
|
# Bug: 24377993
|
|
|
|
epoch = datetime.datetime.fromtimestamp(0)
|
|
|
|
timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
|
|
|
|
image_props["timestamp"] = int(timestamp)
|
|
|
|
|
2017-05-24 08:49:03 +02:00
|
|
|
user_dir = tempfile.mkdtemp()
|
|
|
|
OPTIONS.tempfiles.append(user_dir)
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
fstab = OPTIONS.info_dict["fstab"]
|
|
|
|
if fstab:
|
2015-03-24 03:13:21 +01:00
|
|
|
image_props["fs_type"] = fstab["/cache"].fs_type
|
2014-07-31 20:06:30 +02:00
|
|
|
succ = build_image.BuildImage(user_dir, image_props, img.name)
|
|
|
|
assert succ, "build cache.img image failed"
|
|
|
|
|
|
|
|
common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
|
2017-03-06 04:51:56 +01:00
|
|
|
img.Write()
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
|
2017-06-10 01:58:03 +02:00
|
|
|
def ReplaceUpdatedFiles(zip_filename, files_list):
|
2017-12-15 02:05:33 +01:00
|
|
|
"""Updates all the ZIP entries listed in files_list.
|
2017-05-26 02:38:53 +02:00
|
|
|
|
2017-06-10 01:58:03 +02:00
|
|
|
For now the list includes META/care_map.txt, and the related files under
|
|
|
|
SYSTEM/ after rebuilding recovery.
|
|
|
|
"""
|
2017-12-15 02:05:33 +01:00
|
|
|
common.ZipDelete(zip_filename, files_list)
|
2017-05-26 02:38:53 +02:00
|
|
|
output_zip = zipfile.ZipFile(zip_filename, "a",
|
|
|
|
compression=zipfile.ZIP_DEFLATED,
|
|
|
|
allowZip64=True)
|
2017-06-10 01:58:03 +02:00
|
|
|
for item in files_list:
|
2017-05-26 02:38:53 +02:00
|
|
|
file_path = os.path.join(OPTIONS.input_tmp, item)
|
|
|
|
assert os.path.exists(file_path)
|
|
|
|
common.ZipWrite(output_zip, file_path, arcname=item)
|
|
|
|
common.ZipClose(output_zip)
|
|
|
|
|
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
def AddImagesToTargetFiles(filename):
|
2017-11-20 20:56:43 +01:00
|
|
|
"""Creates and adds images (boot/recovery/system/...) to a target_files.zip.
|
|
|
|
|
|
|
|
It works with either a zip file (zip mode), or a directory that contains the
|
|
|
|
files to be packed into a target_files.zip (dir mode). The latter is used when
|
|
|
|
being called from build/make/core/Makefile.
|
|
|
|
|
|
|
|
The images will be created under IMAGES/ in the input target_files.zip.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filename: the target_files.zip, or the zip root directory.
|
|
|
|
"""
|
2017-03-06 04:51:56 +01:00
|
|
|
if os.path.isdir(filename):
|
|
|
|
OPTIONS.input_tmp = os.path.abspath(filename)
|
|
|
|
input_zip = None
|
|
|
|
else:
|
|
|
|
OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
|
2014-07-31 20:06:30 +02:00
|
|
|
|
2014-11-14 06:41:08 +01:00
|
|
|
if not OPTIONS.add_missing:
|
2017-03-06 04:51:56 +01:00
|
|
|
if os.path.isdir(os.path.join(OPTIONS.input_tmp, "IMAGES")):
|
|
|
|
print("target_files appears to already contain images.")
|
|
|
|
sys.exit(1)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2017-09-12 21:39:09 +02:00
|
|
|
# vendor.img is unlike system.img or system_other.img. Because it could be
|
|
|
|
# built from source, or dropped into target_files.zip as a prebuilt blob. We
|
|
|
|
# consider either of them as vendor.img being available, which could be used
|
|
|
|
# when generating vbmeta.img for AVB.
|
|
|
|
has_vendor = (os.path.isdir(os.path.join(OPTIONS.input_tmp, "VENDOR")) or
|
|
|
|
os.path.exists(os.path.join(OPTIONS.input_tmp, "IMAGES",
|
|
|
|
"vendor.img")))
|
2017-03-06 04:51:56 +01:00
|
|
|
has_system_other = os.path.isdir(os.path.join(OPTIONS.input_tmp,
|
|
|
|
"SYSTEM_OTHER"))
|
2016-06-16 23:47:10 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
if input_zip:
|
|
|
|
OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
common.ZipClose(input_zip)
|
|
|
|
output_zip = zipfile.ZipFile(filename, "a",
|
|
|
|
compression=zipfile.ZIP_DEFLATED,
|
|
|
|
allowZip64=True)
|
|
|
|
else:
|
|
|
|
OPTIONS.info_dict = common.LoadInfoDict(filename, filename)
|
|
|
|
output_zip = None
|
2017-11-20 20:56:43 +01:00
|
|
|
|
|
|
|
# Always make input_tmp/IMAGES available, since we may stage boot / recovery
|
|
|
|
# images there even under zip mode. The directory will be cleaned up as part
|
|
|
|
# of OPTIONS.input_tmp.
|
|
|
|
images_dir = os.path.join(OPTIONS.input_tmp, "IMAGES")
|
|
|
|
if not os.path.isdir(images_dir):
|
|
|
|
os.makedirs(images_dir)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2015-10-28 03:25:18 +01:00
|
|
|
has_recovery = (OPTIONS.info_dict.get("no_recovery") != "true")
|
|
|
|
|
2017-09-28 02:17:43 +02:00
|
|
|
if OPTIONS.info_dict.get("avb_enable") == "true":
|
|
|
|
fp = None
|
|
|
|
if "build.prop" in OPTIONS.info_dict:
|
|
|
|
build_prop = OPTIONS.info_dict["build.prop"]
|
|
|
|
if "ro.build.fingerprint" in build_prop:
|
|
|
|
fp = build_prop["ro.build.fingerprint"]
|
|
|
|
elif "ro.build.thumbprint" in build_prop:
|
|
|
|
fp = build_prop["ro.build.thumbprint"]
|
|
|
|
if fp:
|
|
|
|
OPTIONS.info_dict["avb_salt"] = hashlib.sha256(fp).hexdigest()
|
|
|
|
|
2017-07-12 02:27:55 +02:00
|
|
|
# A map between partition names and their paths, which could be used when
|
|
|
|
# generating AVB vbmeta image.
|
|
|
|
partitions = dict()
|
|
|
|
|
2014-08-26 22:10:25 +02:00
|
|
|
def banner(s):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("\n\n++++ " + s + " ++++\n\n")
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2017-07-12 02:27:55 +02:00
|
|
|
banner("boot")
|
|
|
|
# common.GetBootableImage() returns the image directly if present.
|
|
|
|
boot_image = common.GetBootableImage(
|
|
|
|
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
|
|
|
|
# boot.img may be unavailable in some targets (e.g. aosp_arm64).
|
|
|
|
if boot_image:
|
2017-07-12 02:27:55 +02:00
|
|
|
partitions['boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "boot.img")
|
|
|
|
if not os.path.exists(partitions['boot']):
|
2017-07-12 02:27:55 +02:00
|
|
|
boot_image.WriteToDir(OPTIONS.input_tmp)
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
boot_image.AddToZip(output_zip)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2014-11-14 06:41:08 +01:00
|
|
|
recovery_image = None
|
2015-10-28 03:25:18 +01:00
|
|
|
if has_recovery:
|
|
|
|
banner("recovery")
|
2017-07-12 02:27:55 +02:00
|
|
|
recovery_image = common.GetBootableImage(
|
|
|
|
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
|
|
|
|
assert recovery_image, "Failed to create recovery.img."
|
2017-07-12 02:27:55 +02:00
|
|
|
partitions['recovery'] = os.path.join(
|
2017-07-12 02:27:55 +02:00
|
|
|
OPTIONS.input_tmp, "IMAGES", "recovery.img")
|
2017-07-12 02:27:55 +02:00
|
|
|
if not os.path.exists(partitions['recovery']):
|
2017-07-12 02:27:55 +02:00
|
|
|
recovery_image.WriteToDir(OPTIONS.input_tmp)
|
|
|
|
if output_zip:
|
|
|
|
recovery_image.AddToZip(output_zip)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2016-11-30 21:11:57 +01:00
|
|
|
banner("recovery (two-step image)")
|
|
|
|
# The special recovery.img for two-step package use.
|
|
|
|
recovery_two_step_image = common.GetBootableImage(
|
|
|
|
"IMAGES/recovery-two-step.img", "recovery-two-step.img",
|
|
|
|
OPTIONS.input_tmp, "RECOVERY", two_step_image=True)
|
2017-07-12 02:27:55 +02:00
|
|
|
assert recovery_two_step_image, "Failed to create recovery-two-step.img."
|
|
|
|
recovery_two_step_image_path = os.path.join(
|
|
|
|
OPTIONS.input_tmp, "IMAGES", "recovery-two-step.img")
|
|
|
|
if not os.path.exists(recovery_two_step_image_path):
|
|
|
|
recovery_two_step_image.WriteToDir(OPTIONS.input_tmp)
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
recovery_two_step_image.AddToZip(output_zip)
|
2016-11-30 21:11:57 +01:00
|
|
|
|
2014-08-26 22:10:25 +02:00
|
|
|
banner("system")
|
2017-07-12 02:27:55 +02:00
|
|
|
partitions['system'] = system_img_path = AddSystem(
|
2017-05-31 06:46:33 +02:00
|
|
|
output_zip, recovery_img=recovery_image, boot_img=boot_image)
|
2017-07-12 02:27:55 +02:00
|
|
|
|
2014-08-26 22:10:25 +02:00
|
|
|
if has_vendor:
|
|
|
|
banner("vendor")
|
2017-07-12 02:27:55 +02:00
|
|
|
partitions['vendor'] = vendor_img_path = AddVendor(output_zip)
|
|
|
|
|
2016-06-16 23:47:10 +02:00
|
|
|
if has_system_other:
|
|
|
|
banner("system_other")
|
|
|
|
AddSystemOther(output_zip)
|
2017-07-12 02:27:55 +02:00
|
|
|
|
2016-08-04 04:21:52 +02:00
|
|
|
if not OPTIONS.is_signing:
|
|
|
|
banner("userdata")
|
|
|
|
AddUserdata(output_zip)
|
|
|
|
banner("cache")
|
|
|
|
AddCache(output_zip)
|
2017-05-31 06:46:33 +02:00
|
|
|
|
|
|
|
if OPTIONS.info_dict.get("board_bpt_enable") == "true":
|
2016-04-08 21:08:03 +02:00
|
|
|
banner("partition-table")
|
|
|
|
AddPartitionTable(output_zip)
|
2017-05-31 06:46:33 +02:00
|
|
|
|
|
|
|
if OPTIONS.info_dict.get("has_dtbo") == "true":
|
|
|
|
banner("dtbo")
|
2017-07-12 02:27:55 +02:00
|
|
|
partitions['dtbo'] = AddDtbo(output_zip)
|
2017-05-31 06:46:33 +02:00
|
|
|
|
2017-05-26 12:30:04 +02:00
|
|
|
if OPTIONS.info_dict.get("avb_enable") == "true":
|
Update for new Android Verified Boot (AVB).
This updates the build system for the new Android Verified Boot
codebase. As this is based on Brillo Verified Boot, this change replaces
the existing BVB support.
Android Verified Boot is enabled by the BOARD_AVB_ENABLE variable
BOARD_AVB_ENABLE := true
This will make the build system create vbmeta.img which will contain a
hash descriptor for boot.img, a hashtree descriptor for system.img, a
kernel-cmdline descriptor for setting up dm-verity for system.img and
append a hash-tree to system.img.
Additionally, the descriptors are left in boot.img and system.img so a
third party can create their own vbmeta.img file linking - using the
option --chain_partition - to these images. If this is not needed
footers can be erased using the 'avbtool erase_footer' command. It's
also harmless to just leave them in the images.
By default, the algorithm SHA256_RSA4096 is used with a test key from
the AVB source directory. This can be overriden by the
BOARD_AVB_ALGORITHM and BOARD_AVB_KEY_PATH variables to use e.g. a
4096-bit RSA key and SHA-512:
BOARD_AVB_ALGORITHM := SHA512_RSA4096
BOARD_AVB_KEY_PATH := /path/to/rsa_key_4096bits.pem
To prevent rollback attacks, the rollback index should be increased on a
regular basis. The rollback index can be set with the
BOARD_AVB_ROLLBACK_INDEX variable:
BOARD_AVB_ROLLBACK_INDEX := 5
If this is not set, the rollback index defaults to 0.
The variable BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS can be used to specify
additional options passed to 'avbtool make_vbmeta_image'. Typical
options to be used here include '--prop', '--prop_from_file', and
'--chain_partition'.
The variable BOARD_AVBTOOL_BOOT_ADD_HASH_FOOTER_ARGS can be used to
specify additional options passed to 'avbtool add_hash_footer' for
boot.img. Typical options to be used here include '--hash_algorithm' and
'--salt'.
The variable BOARD_AVBTOOL_SYSTEM_ADD_HASHTREE_FOOTER_ARGS can be used
to specify additional options passed to 'avbtool add_hashtree_footer'
for systems.img. Typical options to be used here include
'--hash_algorithm', '--salt', and '--block_size'.
BUG=31264226
TEST=Manually tested on edison-eng by inspecting {boot, system,
vbmeta}.img in out/ directory as well as their counterparts in
the IMAGES/ directory of edision-target_files-eng.zeuthen.zip
Merged-In: Ic9a61cfc65c148b12996e57f04da5432eef6b982
Change-Id: I97042655bca15e7eac899f12c5bada2f6184d307
2016-09-15 19:43:54 +02:00
|
|
|
banner("vbmeta")
|
2017-07-12 02:27:55 +02:00
|
|
|
AddVBMeta(output_zip, partitions)
|
2014-08-26 22:10:25 +02:00
|
|
|
|
2016-05-11 07:48:13 +02:00
|
|
|
# For devices using A/B update, copy over images from RADIO/ and/or
|
|
|
|
# VENDOR_IMAGES/ to IMAGES/ and make sure we have all the needed
|
|
|
|
# images ready under IMAGES/. All images should have '.img' as extension.
|
2016-06-28 23:34:03 +02:00
|
|
|
banner("radio")
|
2015-11-17 01:32:27 +01:00
|
|
|
ab_partitions = os.path.join(OPTIONS.input_tmp, "META", "ab_partitions.txt")
|
|
|
|
if os.path.exists(ab_partitions):
|
|
|
|
with open(ab_partitions, 'r') as f:
|
|
|
|
lines = f.readlines()
|
2016-03-08 01:31:19 +01:00
|
|
|
# For devices using A/B update, generate care_map for system and vendor
|
|
|
|
# partitions (if present), then write this file to target_files package.
|
|
|
|
care_map_list = []
|
2015-11-17 01:32:27 +01:00
|
|
|
for line in lines:
|
2017-06-01 20:32:32 +02:00
|
|
|
if line.strip() == "system" and (
|
|
|
|
"system_verity_block_device" in OPTIONS.info_dict or
|
2017-06-30 00:11:44 +02:00
|
|
|
OPTIONS.info_dict.get("avb_system_hashtree_enable") == "true"):
|
2016-07-11 20:42:53 +02:00
|
|
|
assert os.path.exists(system_img_path)
|
|
|
|
care_map_list += GetCareMap("system", system_img_path)
|
2017-06-01 20:32:32 +02:00
|
|
|
if line.strip() == "vendor" and (
|
|
|
|
"vendor_verity_block_device" in OPTIONS.info_dict or
|
2017-06-30 00:11:44 +02:00
|
|
|
OPTIONS.info_dict.get("avb_vendor_hashtree_enable") == "true"):
|
2016-07-11 20:42:53 +02:00
|
|
|
assert os.path.exists(vendor_img_path)
|
|
|
|
care_map_list += GetCareMap("vendor", vendor_img_path)
|
2016-03-08 01:31:19 +01:00
|
|
|
|
2015-11-17 01:32:27 +01:00
|
|
|
img_name = line.strip() + ".img"
|
2016-06-28 23:34:03 +02:00
|
|
|
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
|
|
|
|
if os.path.exists(prebuilt_path):
|
2017-01-10 19:47:58 +01:00
|
|
|
print("%s already exists, no need to overwrite..." % (img_name,))
|
2016-06-28 23:34:03 +02:00
|
|
|
continue
|
|
|
|
|
2015-11-17 01:32:27 +01:00
|
|
|
img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
|
|
|
|
if os.path.exists(img_radio_path):
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
common.ZipWrite(output_zip, img_radio_path,
|
|
|
|
os.path.join("IMAGES", img_name))
|
|
|
|
else:
|
|
|
|
shutil.copy(img_radio_path, prebuilt_path)
|
2016-05-11 07:48:13 +02:00
|
|
|
else:
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
img_vendor_dir = os.path.join(OPTIONS.input_tmp, "VENDOR_IMAGES")
|
2016-05-11 07:48:13 +02:00
|
|
|
for root, _, files in os.walk(img_vendor_dir):
|
|
|
|
if img_name in files:
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
common.ZipWrite(output_zip, os.path.join(root, img_name),
|
releasetools: Address pylint warnings in add_img_to_target_files.py.
C:661, 0: Wrong hanging indentation (add 2 spaces).
OPTIONS.input_tmp, "VENDOR_IMAGES")
^ | (bad-continuation)
C:673, 0: Wrong continued indentation (add 14 spaces).
os.path.join("IMAGES", img_name))
^ | (bad-continuation)
C: 54, 0: Import "import datetime" should be placed at the top of the module (wrong-import-position)
C: 55, 0: Import "import hashlib" should be placed at the top of the module (wrong-import-position)
C: 56, 0: Import "import os" should be placed at the top of the module (wrong-import-position)
C: 57, 0: Import "import shlex" should be placed at the top of the module (wrong-import-position)
C: 58, 0: Import "import shutil" should be placed at the top of the module (wrong-import-position)
C: 59, 0: Import "import subprocess" should be placed at the top of the module (wrong-import-position)
C: 60, 0: Import "import tempfile" should be placed at the top of the module (wrong-import-position)
C: 61, 0: Import "import uuid" should be placed at the top of the module (wrong-import-position)
C: 62, 0: Import "import zipfile" should be placed at the top of the module (wrong-import-position)
C: 64, 0: Import "import build_image" should be placed at the top of the module (wrong-import-position)
C: 65, 0: Import "import common" should be placed at the top of the module (wrong-import-position)
C: 66, 0: Import "import rangelib" should be placed at the top of the module (wrong-import-position)
C: 67, 0: Import "import sparse_img" should be placed at the top of the module (wrong-import-position)
W:391,12: Redefining built-in 'dir' (redefined-builtin)
After this CL, it still gives the warning below, which is to be
addressed with follow-ups.
R:635, 2: Too many nested blocks (6/5) (too-many-nested-blocks)
Test: `m dist`
Test: pylint --rcfile=pylintrc add_img_to_target_files.py
Change-Id: I64da184b6b69e93449dbfc989a5d7f46d5223f42
2017-12-02 01:13:22 +01:00
|
|
|
os.path.join("IMAGES", img_name))
|
2017-03-06 04:51:56 +01:00
|
|
|
else:
|
|
|
|
shutil.copy(os.path.join(root, img_name), prebuilt_path)
|
2016-05-11 07:48:13 +02:00
|
|
|
break
|
2015-11-17 01:32:27 +01:00
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
# Zip spec says: All slashes MUST be forward slashes.
|
|
|
|
img_path = 'IMAGES/' + img_name
|
|
|
|
assert img_path in output_zip.namelist(), "cannot find " + img_name
|
|
|
|
else:
|
|
|
|
img_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
|
|
|
|
assert os.path.exists(img_path), "cannot find " + img_name
|
2015-11-17 01:32:27 +01:00
|
|
|
|
2016-03-08 01:31:19 +01:00
|
|
|
if care_map_list:
|
2017-06-10 01:58:03 +02:00
|
|
|
care_map_path = "META/care_map.txt"
|
|
|
|
if output_zip and care_map_path not in output_zip.namelist():
|
|
|
|
common.ZipWriteStr(output_zip, care_map_path, '\n'.join(care_map_list))
|
2017-03-06 04:51:56 +01:00
|
|
|
else:
|
2017-06-10 01:58:03 +02:00
|
|
|
with open(os.path.join(OPTIONS.input_tmp, care_map_path), 'w') as fp:
|
2017-03-06 04:51:56 +01:00
|
|
|
fp.write('\n'.join(care_map_list))
|
2017-06-10 01:58:03 +02:00
|
|
|
if output_zip:
|
|
|
|
OPTIONS.replace_updated_files_list.append(care_map_path)
|
2016-03-08 01:31:19 +01:00
|
|
|
|
2017-06-17 00:30:23 +02:00
|
|
|
# Radio images that need to be packed into IMAGES/, and product-img.zip.
|
|
|
|
pack_radioimages = os.path.join(
|
|
|
|
OPTIONS.input_tmp, "META", "pack_radioimages.txt")
|
|
|
|
if os.path.exists(pack_radioimages):
|
|
|
|
with open(pack_radioimages, 'r') as f:
|
|
|
|
lines = f.readlines()
|
|
|
|
for line in lines:
|
|
|
|
img_name = line.strip()
|
|
|
|
_, ext = os.path.splitext(img_name)
|
|
|
|
if not ext:
|
|
|
|
img_name += ".img"
|
|
|
|
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", img_name)
|
|
|
|
if os.path.exists(prebuilt_path):
|
|
|
|
print("%s already exists, no need to overwrite..." % (img_name,))
|
|
|
|
continue
|
|
|
|
|
|
|
|
img_radio_path = os.path.join(OPTIONS.input_tmp, "RADIO", img_name)
|
|
|
|
assert os.path.exists(img_radio_path), \
|
|
|
|
"Failed to find %s at %s" % (img_name, img_radio_path)
|
|
|
|
if output_zip:
|
|
|
|
common.ZipWrite(output_zip, img_radio_path,
|
|
|
|
os.path.join("IMAGES", img_name))
|
|
|
|
else:
|
|
|
|
shutil.copy(img_radio_path, prebuilt_path)
|
|
|
|
|
2017-03-06 04:51:56 +01:00
|
|
|
if output_zip:
|
|
|
|
common.ZipClose(output_zip)
|
2017-06-10 01:58:03 +02:00
|
|
|
if OPTIONS.replace_updated_files_list:
|
|
|
|
ReplaceUpdatedFiles(output_zip.filename,
|
|
|
|
OPTIONS.replace_updated_files_list)
|
2017-05-26 02:38:53 +02:00
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
def main(argv):
|
2015-09-17 06:20:30 +02:00
|
|
|
def option_handler(o, a):
|
2014-11-14 06:41:08 +01:00
|
|
|
if o in ("-a", "--add_missing"):
|
|
|
|
OPTIONS.add_missing = True
|
|
|
|
elif o in ("-r", "--rebuild_recovery",):
|
|
|
|
OPTIONS.rebuild_recovery = True
|
2015-09-17 06:20:30 +02:00
|
|
|
elif o == "--replace_verity_private_key":
|
|
|
|
OPTIONS.replace_verity_private_key = (True, a)
|
|
|
|
elif o == "--replace_verity_public_key":
|
|
|
|
OPTIONS.replace_verity_public_key = (True, a)
|
2016-08-04 04:21:52 +02:00
|
|
|
elif o == "--is_signing":
|
|
|
|
OPTIONS.is_signing = True
|
2014-11-14 06:41:08 +01:00
|
|
|
else:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2015-03-24 03:13:21 +01:00
|
|
|
args = common.ParseOptions(
|
|
|
|
argv, __doc__, extra_opts="ar",
|
2015-09-17 06:20:30 +02:00
|
|
|
extra_long_opts=["add_missing", "rebuild_recovery",
|
|
|
|
"replace_verity_public_key=",
|
|
|
|
"replace_verity_private_key=",
|
2016-10-18 01:20:12 +02:00
|
|
|
"is_signing"],
|
2015-03-24 03:13:21 +01:00
|
|
|
extra_option_handler=option_handler)
|
2014-11-14 06:41:08 +01:00
|
|
|
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
if len(args) != 1:
|
|
|
|
common.Usage(__doc__)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
AddImagesToTargetFiles(args[0])
|
2017-01-10 19:47:58 +01:00
|
|
|
print("done.")
|
2014-07-31 20:06:30 +02:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
try:
|
|
|
|
common.CloseInheritedPipes()
|
|
|
|
main(sys.argv[1:])
|
2015-03-24 03:13:21 +01:00
|
|
|
except common.ExternalError as e:
|
2017-01-10 19:47:58 +01:00
|
|
|
print("\n ERROR: %s\n" % (e,))
|
2014-07-31 20:06:30 +02:00
|
|
|
sys.exit(1)
|
2014-08-26 22:10:25 +02:00
|
|
|
finally:
|
|
|
|
common.Cleanup()
|