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 -b (--board_config) <file> 24 Deprecated. 25 26 """ 27 28 import sys 29 30 if sys.hexversion < 0x02040000: 31 print >> sys.stderr, "Python 2.4 or newer is required." 32 sys.exit(1) 33 34 import errno 35 import os 36 import re 37 import shutil 38 import subprocess 39 import tempfile 40 import zipfile 41 42 # missing in Python 2.4 and before 43 if not hasattr(os, "SEEK_SET"): 44 os.SEEK_SET = 0 45 46 import common 47 48 OPTIONS = common.OPTIONS 49 50 51 def AddUserdata(output_zip): 52 """Create an empty userdata image and store it in output_zip.""" 53 54 print "creating userdata.img..." 55 56 # The name of the directory it is making an image out of matters to 57 # mkyaffs2image. So we create a temp dir, and within it we create an 58 # empty dir named "data", and build the image from that. 59 temp_dir = tempfile.mkdtemp() 60 user_dir = os.path.join(temp_dir, "data") 61 os.mkdir(user_dir) 62 img = tempfile.NamedTemporaryFile() 63 64 p = common.Run(["mkyaffs2image", "-f", user_dir, img.name]) 65 p.communicate() 66 assert p.returncode == 0, "mkyaffs2image of userdata.img image failed" 67 68 common.CheckSize(img.name, "userdata.img") 69 output_zip.write(img.name, "userdata.img") 70 img.close() 71 os.rmdir(user_dir) 72 os.rmdir(temp_dir) 73 74 75 def AddSystem(output_zip): 76 """Turn the contents of SYSTEM into a system image and store it in 77 output_zip.""" 78 79 print "creating system.img..." 80 81 img = tempfile.NamedTemporaryFile() 82 83 # The name of the directory it is making an image out of matters to 84 # mkyaffs2image. It wants "system" but we have a directory named 85 # "SYSTEM", so create a symlink. 86 try: 87 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"), 88 os.path.join(OPTIONS.input_tmp, "system")) 89 except OSError, e: 90 # bogus error on my mac version? 91 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem 92 # os.path.join(OPTIONS.input_tmp, "system")) 93 # OSError: [Errno 17] File exists 94 if (e.errno == errno.EEXIST): 95 pass 96 97 p = common.Run(["mkyaffs2image", "-f", 98 os.path.join(OPTIONS.input_tmp, "system"), img.name]) 99 p.communicate() 100 assert p.returncode == 0, "mkyaffs2image of system.img image failed" 101 102 img.seek(os.SEEK_SET, 0) 103 data = img.read() 104 img.close() 105 106 common.CheckSize(data, "system.img") 107 common.ZipWriteStr(output_zip, "system.img", data) 108 109 110 def CopyInfo(output_zip): 111 """Copy the android-info.txt file from the input to the output.""" 112 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"), 113 "android-info.txt") 114 115 116 def main(argv): 117 118 def option_handler(o, a): 119 if o in ("-b", "--board_config"): 120 pass # deprecated 121 else: 122 return False 123 return True 124 125 args = common.ParseOptions(argv, __doc__, 126 extra_opts="b:", 127 extra_long_opts=["board_config="], 128 extra_option_handler=option_handler) 129 130 if len(args) != 2: 131 common.Usage(__doc__) 132 sys.exit(1) 133 134 OPTIONS.input_tmp = common.UnzipTemp(args[0]) 135 136 common.LoadMaxSizes() 137 if not OPTIONS.max_image_size: 138 print 139 print " WARNING: Failed to load max image sizes; will not enforce" 140 print " image size limits." 141 print 142 143 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED) 144 145 common.AddBoot(output_zip) 146 common.AddRecovery(output_zip) 147 AddSystem(output_zip) 148 AddUserdata(output_zip) 149 CopyInfo(output_zip) 150 151 print "cleaning up..." 152 output_zip.close() 153 shutil.rmtree(OPTIONS.input_tmp) 154 155 print "done." 156 157 158 if __name__ == '__main__': 159 try: 160 main(sys.argv[1:]) 161 except common.ExternalError, e: 162 print 163 print " ERROR: %s" % (e,) 164 print 165 sys.exit(1) 166