summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-13 02:00:48 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-12-13 02:00:48 +0100
commitf0e2077caea3afc6456b046c66989b780f8c1111 (patch)
tree5410cd542c0f842a3536d74a8a7a5f985808fc18 /tools
parent6662a629cef6f9bcf7edf0885080e3857b8b49b5 (diff)
parentea2aaaeee4322b13eb1fd48342fc8f4a8109a83f (diff)
downloadbuild-f0e2077caea3afc6456b046c66989b780f8c1111.zip
build-f0e2077caea3afc6456b046c66989b780f8c1111.tar.gz
build-f0e2077caea3afc6456b046c66989b780f8c1111.tar.bz2
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_build into replicant-6.0
Diffstat (limited to 'tools')
-rwxr-xr-xtools/buildinfo.sh6
-rwxr-xr-xtools/releasetools/add_img_to_target_files.py47
-rwxr-xr-xtools/releasetools/build_image.py23
-rw-r--r--tools/releasetools/common.py67
-rwxr-xr-xtools/releasetools/img_from_target_files.py3
-rwxr-xr-xtools/releasetools/sign_target_files_apks.py2
-rwxr-xr-xtools/repopick.py46
7 files changed, 175 insertions, 19 deletions
diff --git a/tools/buildinfo.sh b/tools/buildinfo.sh
index 559cd88..fa717b7 100755
--- a/tools/buildinfo.sh
+++ b/tools/buildinfo.sh
@@ -37,7 +37,7 @@ echo "ro.product.cpu.abilist32=$TARGET_CPU_ABI_LIST_32_BIT"
echo "ro.product.cpu.abilist64=$TARGET_CPU_ABI_LIST_64_BIT"
echo "ro.product.manufacturer=$PRODUCT_MANUFACTURER"
-if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then
+if [ -n "$PRODUCT_DEFAULT_LOCALE" ] && [ -z "$TARGET_SKIP_DEFAULT_LOCALE" ] ; then
echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
fi
echo "ro.wifi.channels=$PRODUCT_DEFAULT_WIFI_CHANNELS"
@@ -46,7 +46,9 @@ echo "ro.board.platform=$TARGET_BOARD_PLATFORM"
if [ "$TARGET_UNIFIED_DEVICE" == "" ] ; then
echo "# ro.build.product is obsolete; use ro.product.device"
echo "ro.build.product=$TARGET_DEVICE"
- echo "ro.product.model=$PRODUCT_MODEL"
+ if [ -z "$TARGET_SKIP_PRODUCT_DEVICE" ] ; then
+ echo "ro.product.model=$PRODUCT_MODEL"
+ fi
echo "ro.product.device=$TARGET_DEVICE"
echo "# Do not try to parse description, fingerprint, or thumbprint"
echo "ro.build.description=$PRIVATE_BUILD_DESC"
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index b132963..51d64b8 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -47,7 +47,8 @@ OPTIONS.replace_verity_public_key = False
OPTIONS.replace_verity_private_key = False
OPTIONS.verity_signer_path = None
-def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
+def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None,
+ rebuild_recovery=OPTIONS.rebuild_recovery):
"""Turn the contents of SYSTEM into a system image and store it in
output_zip."""
@@ -61,7 +62,7 @@ def AddSystem(output_zip, prefix="IMAGES/", recovery_img=None, boot_img=None):
ofile.write(data)
ofile.close()
- if OPTIONS.rebuild_recovery:
+ if rebuild_recovery:
print("Building new recovery patch")
common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
boot_img, info_dict=OPTIONS.info_dict)
@@ -100,6 +101,29 @@ def BuildVendor(input_dir, info_dict, block_list=None):
file containing it."""
return CreateImage(input_dir, info_dict, "vendor", block_list=block_list)
+def AddOem(output_zip, prefix="IMAGES/"):
+ """Turn the contents of OEM into a oem image and store in it
+ output_zip."""
+
+ prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "oem.img")
+ if os.path.exists(prebuilt_path):
+ print("oem.img already exists in %s, no need to rebuild..." % prefix)
+ return
+
+ block_list = common.MakeTempFile(prefix="oem-blocklist-", suffix=".map")
+ imgname = BuildOem(OPTIONS.input_tmp, OPTIONS.info_dict,
+ block_list=block_list)
+ with open(imgname, "rb") as f:
+ common.ZipWriteStr(output_zip, prefix + "oem.img", f.read())
+ with open(block_list, "rb") as f:
+ common.ZipWriteStr(output_zip, prefix + "oem.map", f.read())
+
+
+def BuildOem(input_dir, info_dict, block_list=None):
+ """Build the (sparse) oem image and return the name of a temp
+ file containing it."""
+ return CreateImage(input_dir, info_dict, "oem", block_list=block_list)
+
def CreateImage(input_dir, info_dict, what, block_list=None):
print("creating " + what + ".img...")
@@ -299,7 +323,7 @@ def AddCache(output_zip, prefix="IMAGES/"):
os.rmdir(temp_dir)
-def AddImagesToTargetFiles(filename):
+def AddImagesToTargetFiles(filename, rebuild_recovery=OPTIONS.rebuild_recovery):
OPTIONS.input_tmp, input_zip = common.UnzipTemp(filename)
if not OPTIONS.add_missing:
@@ -314,6 +338,12 @@ def AddImagesToTargetFiles(filename):
except KeyError:
has_vendor = False
+ try:
+ input_zip.getinfo("OEM/")
+ has_oem = True
+ except KeyError:
+ has_oem = False
+
OPTIONS.info_dict = common.LoadInfoDict(input_zip)
if "selinux_fc" in OPTIONS.info_dict:
OPTIONS.info_dict["selinux_fc"] = os.path.join(
@@ -331,7 +361,7 @@ def AddImagesToTargetFiles(filename):
boot_image = None
if os.path.exists(prebuilt_path):
print("boot.img already exists in IMAGES/, no need to rebuild...")
- if OPTIONS.rebuild_recovery:
+ if rebuild_recovery:
boot_image = common.GetBootableImage(
"IMAGES/boot.img", "boot.img", OPTIONS.input_tmp, "BOOT")
else:
@@ -345,7 +375,7 @@ def AddImagesToTargetFiles(filename):
prebuilt_path = os.path.join(OPTIONS.input_tmp, "IMAGES", "recovery.img")
if os.path.exists(prebuilt_path):
print("recovery.img already exists in IMAGES/, no need to rebuild...")
- if OPTIONS.rebuild_recovery:
+ if rebuild_recovery:
recovery_image = common.GetBootableImage(
"IMAGES/recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY")
else:
@@ -355,7 +385,8 @@ def AddImagesToTargetFiles(filename):
recovery_image.AddToZip(output_zip)
banner("system")
- AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image)
+ AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image,
+ rebuild_recovery = rebuild_recovery)
if has_vendor:
banner("vendor")
AddVendor(output_zip)
@@ -365,6 +396,10 @@ def AddImagesToTargetFiles(filename):
AddUserdataExtra(output_zip)
banner("cache")
AddCache(output_zip)
+ if has_oem:
+ banner("oem")
+ AddOem(output_zip)
+
common.ZipClose(output_zip)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index efaf7eb..d712083 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -106,15 +106,32 @@ def BuildVerityTree(sparse_image_path, verity_image_path, prop_dict):
def BuildVerityMetadata(image_size, verity_metadata_path, root_hash, salt,
block_device, signer_path, key):
+ verity_key = os.getenv("PRODUCT_VERITY_KEY", None)
+ verity_key_password = None
+
+ if verity_key and os.path.exists(verity_key+".pk8"):
+ verity_key_passwords = {}
+ verity_key_passwords.update(common.PasswordManager().GetPasswords(verity_key.split()))
+ verity_key_password = verity_key_passwords[verity_key]
+
cmd_template = (
"system/extras/verity/build_verity_metadata.py %s %s %s %s %s %s %s")
cmd = cmd_template % (image_size, verity_metadata_path, root_hash, salt,
block_device, signer_path, key)
print(cmd)
- status, output = getstatusoutput(cmd)
- if status:
- print("Could not build verity metadata! Error: %s" % output)
+ runcmd = ["system/extras/verity/build_verity_metadata.py", image_size, verity_metadata_path, root_hash, salt, block_device, signer_path, key];
+ if verity_key_password is not None:
+ sp = subprocess.Popen(runcmd, stdin=subprocess.PIPE)
+ sp.communicate(verity_key_password)
+ else:
+ sp = subprocess.Popen(runcmd)
+
+ sp.wait()
+
+ if sp.returncode != 0:
+ print("Could not build verity metadata!")
return False
+
return True
def Append2Simg(sparse_image_path, unsparse_image_path, error_message):
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 26cc674..32bbc68 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -338,6 +338,9 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
ramdisk_img = tempfile.NamedTemporaryFile()
img = tempfile.NamedTemporaryFile()
+ bootimg_key = os.getenv("PRODUCT_PRIVATE_KEY", None)
+ verity_key = os.getenv("PRODUCT_VERITY_KEY", None)
+ custom_boot_signer = os.getenv("PRODUCT_BOOT_SIGNER", None)
if os.access(fs_config_file, os.F_OK):
cmd = ["mkbootfs", "-f", fs_config_file, os.path.join(sourcedir, "RAMDISK")]
@@ -404,8 +407,9 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
fn = os.path.join(sourcedir, "pagesize")
if os.access(fn, os.F_OK):
+ kernel_pagesize=open(fn).read().rstrip("\n")
cmd.append("--pagesize")
- cmd.append(open(fn).read().rstrip("\n"))
+ cmd.append(kernel_pagesize)
args = info_dict.get("mkbootimg_args", None)
if args and args.strip():
@@ -425,6 +429,50 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
assert p.returncode == 0, "mkbootimg of %s image failed" % (
os.path.basename(sourcedir),)
+ if custom_boot_signer and bootimg_key and os.path.exists(bootimg_key):
+ print("Signing bootable image with custom boot signer...")
+ img_secure = tempfile.NamedTemporaryFile()
+ p = Run([custom_boot_signer, img.name, img_secure.name], stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "signing of bootable image failed"
+ shutil.copyfile(img_secure.name, img.name)
+ img_secure.close()
+ elif bootimg_key and os.path.exists(bootimg_key) and kernel_pagesize > 0:
+ print("Signing bootable image...")
+ bootimg_key_passwords = {}
+ bootimg_key_passwords.update(PasswordManager().GetPasswords(bootimg_key.split()))
+ bootimg_key_password = bootimg_key_passwords[bootimg_key]
+ if bootimg_key_password is not None:
+ bootimg_key_password += "\n"
+ img_sha256 = tempfile.NamedTemporaryFile()
+ img_sig = tempfile.NamedTemporaryFile()
+ img_sig_padded = tempfile.NamedTemporaryFile()
+ img_secure = tempfile.NamedTemporaryFile()
+ p = Run(["openssl", "dgst", "-sha256", "-binary", "-out", img_sha256.name, img.name],
+ stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "signing of bootable image failed"
+ p = Run(["openssl", "rsautl", "-sign", "-in", img_sha256.name, "-inkey", bootimg_key, "-out",
+ img_sig.name, "-passin", "stdin"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ p.communicate(bootimg_key_password)
+ assert p.returncode == 0, "signing of bootable image failed"
+ p = Run(["dd", "if=/dev/zero", "of=%s" % img_sig_padded.name, "bs=%s" % kernel_pagesize,
+ "count=1"], stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "signing of bootable image failed"
+ p = Run(["dd", "if=%s" % img_sig.name, "of=%s" % img_sig_padded.name, "conv=notrunc"],
+ stdout=subprocess.PIPE)
+ p.communicate()
+ assert p.returncode == 0, "signing of bootable image failed"
+ p = Run(["cat", img.name, img_sig_padded.name], stdout=img_secure.file.fileno())
+ p.communicate()
+ assert p.returncode == 0, "signing of bootable image failed"
+ shutil.copyfile(img_secure.name, img.name)
+ img_sha256.close()
+ img_sig.close()
+ img_sig_padded.close()
+ img_secure.close()
+
if (info_dict.get("boot_signer", None) == "true" and
info_dict.get("verity_key", None)):
path = "/" + os.path.basename(sourcedir).lower()
@@ -433,8 +481,21 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None):
cmd.extend([path, img.name,
info_dict["verity_key"] + ".pk8",
info_dict["verity_key"] + ".x509.pem", img.name])
- p = Run(cmd, stdout=subprocess.PIPE)
- p.communicate()
+ verity_key_password = None
+
+ if verity_key and os.path.exists(verity_key+".pk8") and kernel_pagesize > 0:
+ verity_key_passwords = {}
+ verity_key_passwords.update(PasswordManager().GetPasswords(verity_key.split()))
+ verity_key_password = verity_key_passwords[verity_key]
+
+ if verity_key_password is not None:
+ verity_key_password += "\n"
+ p = Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ p.communicate(verity_key_password)
+ else:
+ p = Run(cmd)
+ p.communicate()
+
assert p.returncode == 0, "boot_signer of %s image failed" % path
# Sign the image if vboot is non-empty.
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index d486a7a..33375ca 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -111,6 +111,7 @@ def main(argv):
if os.path.exists(images_path):
# If this is a new target-files, it already contains the images,
# and all we have to do is copy them to the output zip.
+ # Skip oem.img files since they are not needed in fastboot images.
images = os.listdir(images_path)
if images:
for image in images:
@@ -118,6 +119,8 @@ def main(argv):
continue
if not image.endswith(".img"):
continue
+ if image == "oem.img":
+ continue
common.ZipWrite(
output_zip, os.path.join(images_path, image), image)
done = True
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index abdb845..54460e6 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -518,7 +518,7 @@ def main(argv):
common.ZipClose(input_zip)
common.ZipClose(output_zip)
- add_img_to_target_files.AddImagesToTargetFiles(args[1])
+ add_img_to_target_files.AddImagesToTargetFiles(args[1], rebuild_recovery=True)
print("done.")
diff --git a/tools/repopick.py b/tools/repopick.py
index 1840a56..cfbb8a8 100755
--- a/tools/repopick.py
+++ b/tools/repopick.py
@@ -209,7 +209,8 @@ if __name__ == '__main__':
manifest = subprocess.check_output(['repo', 'manifest'])
xml_root = ElementTree.fromstring(manifest)
projects = xml_root.findall('project')
- default_revision = xml_root.findall('default')[0].get('revision').split('/')[-1]
+ remotes = xml_root.findall('remote')
+ default_revision = xml_root.findall('default')[0].get('revision')
#dump project data into the a list of dicts with the following data:
#{project: {path, revision}}
@@ -219,10 +220,15 @@ if __name__ == '__main__':
path = project.get('path')
revision = project.get('revision')
if revision is None:
- revision = default_revision
+ for remote in remotes:
+ if remote.get('name') == project.get('remote'):
+ revision = remote.get('revision')
+ if revision is None:
+ revision = default_revision
if not name in project_name_to_data:
project_name_to_data[name] = {}
+ revision = revision.split('refs/heads/')[-1]
project_name_to_data[name][revision] = path
# get data on requested changes
@@ -235,8 +241,14 @@ if __name__ == '__main__':
reviews = fetch_query(args.gerrit, args.query)
change_numbers = sorted([str(r['number']) for r in reviews])
if args.change_number:
- reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in args.change_number))
- change_numbers = args.change_number
+ for c in args.change_number:
+ if '-' in c:
+ templist = c.split('-')
+ for i in range(int(templist[0]), int(templist[1]) + 1):
+ change_numbers.append(str(i))
+ else:
+ change_numbers.append(c)
+ reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in change_numbers))
# make list of things to actually merge
mergables = []
@@ -264,6 +276,7 @@ if __name__ == '__main__':
'subject': review['subject'],
'project': review['project'],
'branch': review['branch'],
+ 'change_id': review['change_id'],
'change_number': review['number'],
'status': review['status'],
'fetch': None
@@ -306,6 +319,31 @@ if __name__ == '__main__':
if args.start_branch:
subprocess.check_output(['repo', 'start', args.start_branch[0], project_path])
+ # Determine the maximum commits to check already picked changes
+ check_picked_count = 10
+ branch_commits_count = int(subprocess.check_output(['git', 'rev-list', '--count', 'HEAD'], cwd=project_path))
+ if branch_commits_count <= check_picked_count:
+ check_picked_count = branch_commits_count - 1
+
+ # Check if change is already picked to HEAD...HEAD~check_picked_count
+ found_change = False
+ for i in range(0, check_picked_count):
+ if subprocess.call(['git', 'cat-file', '-e', 'HEAD~{0}'.format(i)], cwd=project_path, stderr=open(os.devnull, 'wb')):
+ continue
+ output = subprocess.check_output(['git', 'show', '-q', 'HEAD~{0}'.format(i)], cwd=project_path).split()
+ if 'Change-Id:' in output:
+ head_change_id = ''
+ for j,t in enumerate(reversed(output)):
+ if t == 'Change-Id:':
+ head_change_id = output[len(output) - j]
+ break
+ if head_change_id.strip() == item['change_id']:
+ print('Skipping {0} - already picked in {1} as HEAD~{2}'.format(item['id'], project_path, i))
+ found_change = True
+ break
+ if found_change:
+ continue
+
# Print out some useful info
if not args.quiet:
print('--> Subject: "{0}"'.format(item['subject']))