blob: f83188ed10ff7c56bfa032a39a85c61ce56f87b6 [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 Wang933abf12010-06-16 14:31:34 -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 Default 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 Wang933abf12010-06-16 14:31:34 -070055class UserImageOptions(object): pass
56USERIMAGE_OPTIONS = UserImageOptions()
57USERIMAGE_OPTIONS.fs_type = None
58
Doug Zongkereef39442009-04-02 12:14:19 -070059
60def AddUserdata(output_zip):
61 """Create an empty userdata image and store it in output_zip."""
62
63 print "creating userdata.img..."
64
65 # The name of the directory it is making an image out of matters to
66 # mkyaffs2image. So we create a temp dir, and within it we create an
67 # empty dir named "data", and build the image from that.
68 temp_dir = tempfile.mkdtemp()
69 user_dir = os.path.join(temp_dir, "data")
70 os.mkdir(user_dir)
71 img = tempfile.NamedTemporaryFile()
72
Ying Wang933abf12010-06-16 14:31:34 -070073 build_command = []
74 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
75 build_command = ["mkuserimg.sh",
76 user_dir, img.name, USERIMAGE_OPTIONS.fs_type, "userdata"]
77 else:
78 build_command = ["mkyaffs2image", "-f",
79 user_dir, img.name]
80
81 p = common.Run(build_command);
Doug Zongkereef39442009-04-02 12:14:19 -070082 p.communicate()
Ying Wang933abf12010-06-16 14:31:34 -070083 assert p.returncode == 0, "build userdata.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -070084
85 common.CheckSize(img.name, "userdata.img")
86 output_zip.write(img.name, "userdata.img")
87 img.close()
88 os.rmdir(user_dir)
89 os.rmdir(temp_dir)
90
91
92def AddSystem(output_zip):
93 """Turn the contents of SYSTEM into a system image and store it in
94 output_zip."""
95
96 print "creating system.img..."
97
98 img = tempfile.NamedTemporaryFile()
99
100 # The name of the directory it is making an image out of matters to
101 # mkyaffs2image. It wants "system" but we have a directory named
102 # "SYSTEM", so create a symlink.
Mike Rittere44fade2009-09-15 11:18:31 -0700103 try:
104 os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
105 os.path.join(OPTIONS.input_tmp, "system"))
106 except OSError, e:
107 # bogus error on my mac version?
108 # File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
109 # os.path.join(OPTIONS.input_tmp, "system"))
110 # OSError: [Errno 17] File exists
111 if (e.errno == errno.EEXIST):
112 pass
Doug Zongkereef39442009-04-02 12:14:19 -0700113
Ying Wang933abf12010-06-16 14:31:34 -0700114 build_command = []
115 if USERIMAGE_OPTIONS.fs_type is not None and USERIMAGE_OPTIONS.fs_type.startswith("ext"):
116 build_command = ["mkuserimg.sh",
117 os.path.join(OPTIONS.input_tmp, "system"), img.name,
118 USERIMAGE_OPTIONS.fs_type, "system"]
119 else:
120 build_command = ["mkyaffs2image", "-f",
121 os.path.join(OPTIONS.input_tmp, "system"), img.name]
122
123 p = common.Run(build_command)
Doug Zongkereef39442009-04-02 12:14:19 -0700124 p.communicate()
Ying Wang933abf12010-06-16 14:31:34 -0700125 assert p.returncode == 0, "build system.img image failed"
Doug Zongkereef39442009-04-02 12:14:19 -0700126
127 img.seek(os.SEEK_SET, 0)
128 data = img.read()
129 img.close()
130
131 common.CheckSize(data, "system.img")
Doug Zongker048e7ca2009-06-15 14:31:53 -0700132 common.ZipWriteStr(output_zip, "system.img", data)
Doug Zongkereef39442009-04-02 12:14:19 -0700133
134
135def CopyInfo(output_zip):
136 """Copy the android-info.txt file from the input to the output."""
137 output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
138 "android-info.txt")
139
140
141def main(argv):
142
143 def option_handler(o, a):
144 if o in ("-b", "--board_config"):
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700145 pass # deprecated
Ying Wang933abf12010-06-16 14:31:34 -0700146 elif o in ("-f", "--fs_type"):
147 USERIMAGE_OPTIONS.fs_type = a
Doug Zongkereef39442009-04-02 12:14:19 -0700148 else:
149 return False
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700150 return True
Doug Zongkereef39442009-04-02 12:14:19 -0700151
152 args = common.ParseOptions(argv, __doc__,
Ying Wang933abf12010-06-16 14:31:34 -0700153 extra_opts="b:f:",
154 extra_long_opts=["board_config=", "fs_type="],
Doug Zongkereef39442009-04-02 12:14:19 -0700155 extra_option_handler=option_handler)
156
157 if len(args) != 2:
158 common.Usage(__doc__)
159 sys.exit(1)
160
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700161 OPTIONS.input_tmp = common.UnzipTemp(args[0])
162
163 common.LoadMaxSizes()
Doug Zongkereef39442009-04-02 12:14:19 -0700164 if not OPTIONS.max_image_size:
165 print
Doug Zongkerfdd8e692009-08-03 17:27:48 -0700166 print " WARNING: Failed to load max image sizes; will not enforce"
167 print " image size limits."
Doug Zongkereef39442009-04-02 12:14:19 -0700168 print
169
Doug Zongkereef39442009-04-02 12:14:19 -0700170 output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
171
172 common.AddBoot(output_zip)
173 common.AddRecovery(output_zip)
174 AddSystem(output_zip)
175 AddUserdata(output_zip)
176 CopyInfo(output_zip)
177
178 print "cleaning up..."
179 output_zip.close()
180 shutil.rmtree(OPTIONS.input_tmp)
181
182 print "done."
183
184
185if __name__ == '__main__':
186 try:
187 main(sys.argv[1:])
188 except common.ExternalError, e:
189 print
190 print " ERROR: %s" % (e,)
191 print
192 sys.exit(1)