blob: 98a00fb0bf677aa7e10259299f18c76a670c9985 [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
86 common.CheckSize(img.name, "userdata.img")
87 output_zip.write(img.name, "userdata.img")
88 img.close()
89 os.rmdir(user_dir)
90 os.rmdir(temp_dir)
91
92
93def AddSystem(output_zip):
94 """Turn the contents of SYSTEM into a system image and store it in
95 output_zip."""
96
97 print "creating system.img..."
98
99 img = tempfile.NamedTemporaryFile()
100
101 # The name of the directory it is making an image out of matters to
102 # mkyaffs2image. It wants "system" but we have a directory named
103 # "SYSTEM", so create a symlink.
Mike Rittere44fade2009-09-15 11:18:31 -0700104 try:
105 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
106 os.path.join(OPTIONS.input_tmp, "system"))
107 except OSError, e:
108 # bogus error on my mac version?
109 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
110 # os.path.join(OPTIONS.input_tmp, "system"))
111 # OSError: [Errno 17] File exists
112 if (e.errno == errno.EEXIST):
113 pass
Doug Zongkereef39442009-04-02 12:14:19 -0700114
Ying Wang065521b2010-08-23 11:34:40 -0700115 build_command = []
116 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
117 build_command = ["mkuserimg.sh",
118 os.path.join(OPTIONS.input_tmp, "system"), img.name,
119 USERIMAGE_OPTIONS.fs_type, "system"]
120 if "system.img" in OPTIONS.max_image_size:
121 build_command.append(str(OPTIONS.max_image_size["system.img"]))
122 else:
123 build_command = ["mkyaffs2image", "-f",
124 os.path.join(OPTIONS.input_tmp, "system"), img.name]
125
126 p = common.Run(build_command)
Doug Zongkereef39442009-04-02 12:14:19 -0700127 p.communicate()
Ying Wang065521b2010-08-23 11:34:40 -0700128 assert p.returncode == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700129
130 img.seek(os.SEEK_SET, 0)
131 data = img.read()
132 img.close()
133
134 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700135 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700136
137
138def CopyInfo(output_zip):
139 """Copy the android-info.txt file from the input to the output."""
140 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
141 "android-info.txt")
142
143
144def main(argv):
145
146 def option_handler(o, a):
147 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700148 pass # deprecated
Ying Wang065521b2010-08-23 11:34:40 -0700149 elif o in ("-f", "--fs_type"):
150 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700151 else:
152 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700153 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700154
155 args = common.ParseOptions(argv, __doc__,
Ying Wang065521b2010-08-23 11:34:40 -0700156 extra_opts="b:f:",
157 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700158 extra_option_handler=option_handler)
159
160 if len(args) != 2:
161 common.Usage(__doc__)
162 sys.exit(1)
163
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700164 OPTIONS.input_tmp = common.UnzipTemp(args[0])
165
166 common.LoadMaxSizes()
Doug Zongkereef39442009-04-02 12:14:19 -0700167 if not OPTIONS.max_image_size:
168 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700169 print " WARNING: Failed to load max image sizes; will not enforce"
170 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700171 print
172
Doug Zongkereef39442009-04-02 12:14:19 -0700173 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
174
175 common.AddBoot(output_zip)
176 common.AddRecovery(output_zip)
177 AddSystem(output_zip)
178 AddUserdata(output_zip)
179 CopyInfo(output_zip)
180
181 print "cleaning up..."
182 output_zip.close()
183 shutil.rmtree(OPTIONS.input_tmp)
184
185 print "done."
186
187
188if __name__ == '__main__':
189 try:
190 main(sys.argv[1:])
191 except common.ExternalError, e:
192 print
193 print " ERROR: %s" % (e,)
194 print
195 sys.exit(1)