blob: 44bed9c3fd12bfc81992c54be46556fd550089cb [file] [log] [blame]
Doug Zongkereef39442009-04-02 12:14:19 -07001#!/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"""
18Given a target-files zipfile, produces an image zipfile suitable for
19use with 'fastboot update'.
20
21Usage: img_from_target_files [flags] input_target_files output_image_zip
22
23 -b (--board_config) <file>
Doug Zongkerfdd8e692009-08-03 17:27:48 -070024 Deprecated.
Doug Zongkereef39442009-04-02 12:14:19 -070025
Ying Wang065521b2010-08-23 11:34:40 -070026 -f (--fs_type) <value>
27 The file system type of the user image files to be created.
28 It can be ext fs variants, such as ext2, ext3, ext4, etc.
29 efault is yaffs.
30
Doug Zongkereef39442009-04-02 12:14:19 -070031"""
32
33import sys
34
35if sys.hexversion < 0x02040000:
36 print >> sys.stderr, "Python 2.4 or newer is required."
37 sys.exit(1)
38
Mike Rittere44fade2009-09-15 11:18:31 -070039import errno
Doug Zongkereef39442009-04-02 12:14:19 -070040import os
41import re
42import shutil
43import subprocess
44import tempfile
45import zipfile
46
47# missing in Python 2.4 and before
48if not hasattr(os, "SEEK_SET"):
49 os.SEEK_SET = 0
50
51import common
52
53OPTIONS = common.OPTIONS
54
Ying Wang065521b2010-08-23 11:34:40 -070055class UserImageOptions(object): pass
56USERIMAGE_OPTIONS = UserImageOptions()
57USERIMAGE_OPTIONS.fs_type = None
Doug Zongkereef39442009-04-02 12:14:19 -070058
59def AddUserdata(output_zip):
60 """Create an empty userdata image and store it in output_zip."""
61
62 print "creating userdata.img..."
63
64 # The name of the directory it is making an image out of matters to
65 # mkyaffs2image. So we create a temp dir, and within it we create an
66 # empty dir named "data", and build the image from that.
67 temp_dir = tempfile.mkdtemp()
68 user_dir = os.path.join(temp_dir, "data")
69 os.mkdir(user_dir)
70 img = tempfile.NamedTemporaryFile()
71
Ying Wang065521b2010-08-23 11:34:40 -070072 build_command = []
73 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
74 build_command = ["mkuserimg.sh",
75 user_dir, img.name, USERIMAGE_OPTIONS.fs_type, "userdata"]
76 if "userdata.img" in OPTIONS.max_image_size:
77 build_command.append(str(OPTIONS.max_image_size["userdata.img"]))
78 else:
79 build_command = ["mkyaffs2image", "-f",
80 user_dir, img.name]
81
82 p = common.Run(build_command)
Doug Zongkereef39442009-04-02 12:14:19 -070083 p.communicate()
Ying Wang065521b2010-08-23 11:34:40 -070084 assert p.returncode == 0, "build userdata.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -070085
Ying Wangee4bad52010-08-24 11:18:07 -070086 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
87 common.CheckSize(img.name, "userdata.img")
Doug Zongkereef39442009-04-02 12:14:19 -070088 output_zip.write(img.name, "userdata.img")
89 img.close()
90 os.rmdir(user_dir)
91 os.rmdir(temp_dir)
92
93
94def AddSystem(output_zip):
95 """Turn the contents of SYSTEM into a system image and store it in
96 output_zip."""
97
98 print "creating system.img..."
99
100 img = tempfile.NamedTemporaryFile()
101
102 # The name of the directory it is making an image out of matters to
103 # mkyaffs2image. It wants "system" but we have a directory named
104 # "SYSTEM", so create a symlink.
Mike Rittere44fade2009-09-15 11:18:31 -0700105 try:
106 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
107 os.path.join(OPTIONS.input_tmp, "system"))
108 except OSError, e:
109 # bogus error on my mac version?
110 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
111 # os.path.join(OPTIONS.input_tmp, "system"))
112 # OSError: [Errno 17] File exists
113 if (e.errno == errno.EEXIST):
114 pass
Doug Zongkereef39442009-04-02 12:14:19 -0700115
Ying Wang065521b2010-08-23 11:34:40 -0700116 build_command = []
117 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
118 build_command = ["mkuserimg.sh",
119 os.path.join(OPTIONS.input_tmp, "system"), img.name,
120 USERIMAGE_OPTIONS.fs_type, "system"]
121 if "system.img" in OPTIONS.max_image_size:
122 build_command.append(str(OPTIONS.max_image_size["system.img"]))
123 else:
124 build_command = ["mkyaffs2image", "-f",
125 os.path.join(OPTIONS.input_tmp, "system"), img.name]
126
127 p = common.Run(build_command)
Doug Zongkereef39442009-04-02 12:14:19 -0700128 p.communicate()
Ying Wang065521b2010-08-23 11:34:40 -0700129 assert p.returncode == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700130
131 img.seek(os.SEEK_SET, 0)
132 data = img.read()
133 img.close()
134
Ying Wangee4bad52010-08-24 11:18:07 -0700135 if USERIMAGE_OPTIONS.fs_type is None or not USERIMAGE_OPTIONS.fs_type.startswith("ext"):
136 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700137 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700138
139
140def CopyInfo(output_zip):
141 """Copy the android-info.txt file from the input to the output."""
142 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
143 "android-info.txt")
144
145
146def main(argv):
147
148 def option_handler(o, a):
149 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700150 pass # deprecated
Ying Wang065521b2010-08-23 11:34:40 -0700151 elif o in ("-f", "--fs_type"):
152 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700153 else:
154 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700155 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700156
157 args = common.ParseOptions(argv, __doc__,
Ying Wang065521b2010-08-23 11:34:40 -0700158 extra_opts="b:f:",
159 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700160 extra_option_handler=option_handler)
161
162 if len(args) != 2:
163 common.Usage(__doc__)
164 sys.exit(1)
165
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700166 OPTIONS.input_tmp = common.UnzipTemp(args[0])
167
168 common.LoadMaxSizes()
Doug Zongkereef39442009-04-02 12:14:19 -0700169 if not OPTIONS.max_image_size:
170 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700171 print " WARNING: Failed to load max image sizes; will not enforce"
172 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700173 print
174
Doug Zongkereef39442009-04-02 12:14:19 -0700175 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
176
177 common.AddBoot(output_zip)
178 common.AddRecovery(output_zip)
179 AddSystem(output_zip)
180 AddUserdata(output_zip)
181 CopyInfo(output_zip)
182
183 print "cleaning up..."
184 output_zip.close()
185 shutil.rmtree(OPTIONS.input_tmp)
186
187 print "done."
188
189
190if __name__ == '__main__':
191 try:
192 main(sys.argv[1:])
193 except common.ExternalError, e:
194 print
195 print " ERROR: %s" % (e,)
196 print
197 sys.exit(1)