xref: /aosp_15_r20/build/make/tools/releasetools/create_brick_ota.py (revision 9e94795a3d4ef5c1d47486f9a02bb378756cea8a)
1*9e94795aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*9e94795aSAndroid Build Coastguard Worker#
3*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2023 The Android Open Source Project
4*9e94795aSAndroid Build Coastguard Worker#
5*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*9e94795aSAndroid Build Coastguard Worker#
9*9e94795aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
10*9e94795aSAndroid Build Coastguard Worker#
11*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*9e94795aSAndroid Build Coastguard Worker# limitations under the License.
16*9e94795aSAndroid Build Coastguard Worker#
17*9e94795aSAndroid Build Coastguard Worker
18*9e94795aSAndroid Build Coastguard Workerimport argparse
19*9e94795aSAndroid Build Coastguard Workerfrom pathlib import Path
20*9e94795aSAndroid Build Coastguard Workerimport zipfile
21*9e94795aSAndroid Build Coastguard Workerfrom typing import List
22*9e94795aSAndroid Build Coastguard Workerimport common
23*9e94795aSAndroid Build Coastguard Workerimport tempfile
24*9e94795aSAndroid Build Coastguard Workerimport shutil
25*9e94795aSAndroid Build Coastguard Worker
26*9e94795aSAndroid Build Coastguard WorkerPARTITIONS_TO_WIPE = ["/dev/block/by-name/vbmeta",
27*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vbmeta_a",
28*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vbmeta_b",
29*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vbmeta_system_a",
30*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vbmeta_system_b",
31*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/boot",
32*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/boot_a",
33*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/boot_b",
34*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vendor_boot",
35*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vendor_boot_a",
36*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/vendor_boot_b",
37*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/init_boot_a",
38*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/init_boot_b",
39*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/metadata",
40*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/super",
41*9e94795aSAndroid Build Coastguard Worker                      "/dev/block/by-name/userdata"]
42*9e94795aSAndroid Build Coastguard Worker
43*9e94795aSAndroid Build Coastguard Worker
44*9e94795aSAndroid Build Coastguard Workerdef CreateBrickOta(product_name: str, output_path: Path, extra_wipe_partitions: str, serialno: str):
45*9e94795aSAndroid Build Coastguard Worker  partitions_to_wipe = PARTITIONS_TO_WIPE
46*9e94795aSAndroid Build Coastguard Worker  if extra_wipe_partitions is not None:
47*9e94795aSAndroid Build Coastguard Worker    partitions_to_wipe = PARTITIONS_TO_WIPE + extra_wipe_partitions.split(",")
48*9e94795aSAndroid Build Coastguard Worker  ota_metadata = ["ota-type=BRICK", "post-timestamp=9999999999",
49*9e94795aSAndroid Build Coastguard Worker                  "pre-device=" + product_name]
50*9e94795aSAndroid Build Coastguard Worker  if serialno is not None:
51*9e94795aSAndroid Build Coastguard Worker      ota_metadata.append("serialno=" + serialno)
52*9e94795aSAndroid Build Coastguard Worker  # recovery requiers product name to be a | separated list
53*9e94795aSAndroid Build Coastguard Worker  product_name = product_name.replace(",", "|")
54*9e94795aSAndroid Build Coastguard Worker  with zipfile.ZipFile(output_path, "w") as zfp:
55*9e94795aSAndroid Build Coastguard Worker    zfp.writestr("recovery.wipe", "\n".join(partitions_to_wipe))
56*9e94795aSAndroid Build Coastguard Worker    zfp.writestr("payload.bin", "")
57*9e94795aSAndroid Build Coastguard Worker    zfp.writestr("META-INF/com/android/metadata", "\n".join(
58*9e94795aSAndroid Build Coastguard Worker        ota_metadata))
59*9e94795aSAndroid Build Coastguard Worker
60*9e94795aSAndroid Build Coastguard Worker
61*9e94795aSAndroid Build Coastguard Workerdef main(argv):
62*9e94795aSAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(description='Android Brick OTA generator')
63*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('otafile', metavar='PAYLOAD', type=str,
64*9e94795aSAndroid Build Coastguard Worker                      help='The output OTA package file.')
65*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--product', type=str,
66*9e94795aSAndroid Build Coastguard Worker                      help='The product name of the device, for example, bramble, redfin.', required=True)
67*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--serialno', type=str,
68*9e94795aSAndroid Build Coastguard Worker                      help='The serial number of devices that are allowed to install this OTA package. This can be a | separated list.')
69*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--extra_wipe_partitions', type=str,
70*9e94795aSAndroid Build Coastguard Worker                      help='Additional partitions on device which should be wiped.')
71*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('-v', action="store_true",
72*9e94795aSAndroid Build Coastguard Worker                      help="Enable verbose logging", dest="verbose")
73*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--package_key', type=str,
74*9e94795aSAndroid Build Coastguard Worker                      help='Paths to private key for signing payload')
75*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--search_path', type=str,
76*9e94795aSAndroid Build Coastguard Worker                      help='Search path for framework/signapk.jar')
77*9e94795aSAndroid Build Coastguard Worker  parser.add_argument('--private_key_suffix', type=str,
78*9e94795aSAndroid Build Coastguard Worker                      help='Suffix to be appended to package_key path', default=".pk8")
79*9e94795aSAndroid Build Coastguard Worker  args = parser.parse_args(argv[1:])
80*9e94795aSAndroid Build Coastguard Worker  if args.search_path:
81*9e94795aSAndroid Build Coastguard Worker    common.OPTIONS.search_path = args.search_path
82*9e94795aSAndroid Build Coastguard Worker  if args.verbose:
83*9e94795aSAndroid Build Coastguard Worker    common.OPTIONS.verbose = args.verbose
84*9e94795aSAndroid Build Coastguard Worker  CreateBrickOta(args.product, args.otafile,
85*9e94795aSAndroid Build Coastguard Worker                 args.extra_wipe_partitions, args.serialno)
86*9e94795aSAndroid Build Coastguard Worker  if args.package_key:
87*9e94795aSAndroid Build Coastguard Worker    common.OPTIONS.private_key_suffix = args.private_key_suffix
88*9e94795aSAndroid Build Coastguard Worker    with tempfile.NamedTemporaryFile() as tmpfile:
89*9e94795aSAndroid Build Coastguard Worker      common.SignFile(args.otafile, tmpfile.name,
90*9e94795aSAndroid Build Coastguard Worker                      args.package_key, None, whole_file=True)
91*9e94795aSAndroid Build Coastguard Worker      shutil.copy(tmpfile.name, args.otafile)
92*9e94795aSAndroid Build Coastguard Worker
93*9e94795aSAndroid Build Coastguard Worker
94*9e94795aSAndroid Build Coastguard Workerif __name__ == "__main__":
95*9e94795aSAndroid Build Coastguard Worker  import sys
96*9e94795aSAndroid Build Coastguard Worker  main(sys.argv)
97