Home | History | Annotate | Download | only in releasetools
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2008 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 
     17 """
     18 Given a target-files zipfile, produces an image zipfile suitable for
     19 use with 'fastboot update'.
     20 
     21 Usage:  img_from_target_files [flags] input_target_files output_image_zip
     22 
     23   -z  (--bootable_zip)
     24       Include only the bootable images (eg 'boot' and 'recovery') in
     25       the output.
     26 
     27 """
     28 
     29 from __future__ import print_function
     30 
     31 import sys
     32 
     33 if sys.hexversion < 0x02070000:
     34   print("Python 2.7 or newer is required.", file=sys.stderr)
     35   sys.exit(1)
     36 
     37 import os
     38 import shutil
     39 import zipfile
     40 
     41 import common
     42 
     43 OPTIONS = common.OPTIONS
     44 
     45 
     46 def CopyInfo(output_zip):
     47   """Copy the android-info.txt file from the input to the output."""
     48   common.ZipWrite(
     49       output_zip, os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
     50       "android-info.txt")
     51 
     52 
     53 def main(argv):
     54   bootable_only = [False]
     55 
     56   def option_handler(o, _):
     57     if o in ("-z", "--bootable_zip"):
     58       bootable_only[0] = True
     59     else:
     60       return False
     61     return True
     62 
     63   args = common.ParseOptions(argv, __doc__,
     64                              extra_opts="z",
     65                              extra_long_opts=["bootable_zip"],
     66                              extra_option_handler=option_handler)
     67 
     68   bootable_only = bootable_only[0]
     69 
     70   if len(args) != 2:
     71     common.Usage(__doc__)
     72     sys.exit(1)
     73 
     74   OPTIONS.input_tmp, input_zip = common.UnzipTemp(
     75       args[0], ["IMAGES/*", "OTA/*"])
     76   output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
     77   CopyInfo(output_zip)
     78 
     79   try:
     80     images_path = os.path.join(OPTIONS.input_tmp, "IMAGES")
     81     # A target-files zip must contain the images since Lollipop.
     82     assert os.path.exists(images_path)
     83     for image in sorted(os.listdir(images_path)):
     84       if bootable_only and image not in ("boot.img", "recovery.img"):
     85         continue
     86       if not image.endswith(".img"):
     87         continue
     88       if image == "recovery-two-step.img":
     89         continue
     90       common.ZipWrite(output_zip, os.path.join(images_path, image), image)
     91 
     92   finally:
     93     print("cleaning up...")
     94     common.ZipClose(output_zip)
     95     shutil.rmtree(OPTIONS.input_tmp)
     96 
     97   print("done.")
     98 
     99 
    100 if __name__ == '__main__':
    101   try:
    102     common.CloseInheritedPipes()
    103     main(sys.argv[1:])
    104   except common.ExternalError as e:
    105     print("\n   ERROR: %s\n" % (e,))
    106     sys.exit(1)
    107