1eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#!/usr/bin/env python
2eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#
3eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Copyright (C) 2008 The Android Open Source Project
4eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#
5eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Licensed under the Apache License, Version 2.0 (the "License");
6eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# you may not use this file except in compliance with the License.
7eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# You may obtain a copy of the License at
8eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#
9eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#      http://www.apache.org/licenses/LICENSE-2.0
10eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker#
11eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# Unless required by applicable law or agreed to in writing, software
12eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# distributed under the License is distributed on an "AS IS" BASIS,
13eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# See the License for the specific language governing permissions and
15eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# limitations under the License.
16eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
17eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker"""
18eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerGiven a target-files zipfile, produces an image zipfile suitable for
19eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkeruse with 'fastboot update'.
20eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
21eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerUsage:  img_from_target_files [flags] input_target_files output_image_zip
22eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
23eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  -b  (--board_config)  <file>
24fdd8e69c42e66fb70384bcaca1747f504f2c021cDoug Zongker      Deprecated.
25eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
2655d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  -z  (--bootable_zip)
2755d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      Include only the bootable images (eg 'boot' and 'recovery') in
2855d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      the output.
2955d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker
30eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker"""
31eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
32eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport sys
33eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
34eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif sys.hexversion < 0x02040000:
35eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  print >> sys.stderr, "Python 2.4 or newer is required."
36eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  sys.exit(1)
37eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
38e44fadeb49aac9d762f089ee2f23e4a4907a822fMike Ritterimport errno
39eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport os
40eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport re
41eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport shutil
42eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport subprocess
43eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport tempfile
44eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport zipfile
45eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
46eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker# missing in Python 2.4 and before
47eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif not hasattr(os, "SEEK_SET"):
48eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  os.SEEK_SET = 0
49eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
50bd93d425aedef907d8fef643b748897e9c7dceebYing Wangimport build_image
51eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerimport common
52eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
53eef3944eb3673329b5e89cf188ac592805a0b08dDoug ZongkerOPTIONS = common.OPTIONS
54eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
55a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
56a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wangdef AddSystem(output_zip):
57a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  """Turn the contents of SYSTEM into a system image and store it in
58a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  output_zip."""
59a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
60a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  print "creating system.img..."
61a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
62a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img = tempfile.NamedTemporaryFile()
63a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
64a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # The name of the directory it is making an image out of matters to
65a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # mkyaffs2image.  It wants "system" but we have a directory named
66a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # "SYSTEM", so create a symlink.
67a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  try:
68a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    os.symlink(os.path.join(OPTIONS.input_tmp, "SYSTEM"),
69a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang               os.path.join(OPTIONS.input_tmp, "system"))
70a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  except OSError, e:
71a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      # bogus error on my mac version?
72a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      #   File "./build/tools/releasetools/img_from_target_files", line 86, in AddSystem
73a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      #     os.path.join(OPTIONS.input_tmp, "system"))
74a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      # OSError: [Errno 17] File exists
75a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    if (e.errno == errno.EEXIST):
76a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      pass
77a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
78a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
79a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang                                                    "system")
80a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  fstab = OPTIONS.info_dict["fstab"]
81a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  if fstab:
82a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    image_props["fs_type" ] = fstab["/system"].fs_type
83a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  succ = build_image.BuildImage(os.path.join(OPTIONS.input_tmp, "system"),
84a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang                                image_props, img.name)
85a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  assert succ, "build system.img image failed"
86a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
87a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img.seek(os.SEEK_SET, 0)
88a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  data = img.read()
89a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img.close()
90a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
91a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  common.CheckSize(data, "system.img", OPTIONS.info_dict)
92a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  common.ZipWriteStr(output_zip, "system.img", data)
93a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
94a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
95a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wangdef AddVendor(output_zip):
96a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  """Turn the contents of VENDOR into vendor.img and store it in
97a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  output_zip."""
98a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
99a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
100a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang                                                    "vendor")
101a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # The build system has to explicitly request for vendor.img.
102a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  if "fs_type" not in image_props:
103a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    return
104a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
105a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  print "creating vendor.img..."
106a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
107a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img = tempfile.NamedTemporaryFile()
108a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
109a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # The name of the directory it is making an image out of matters to
110a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # mkyaffs2image.  It wants "vendor" but we have a directory named
111a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # "VENDOR", so create a symlink or an empty directory if VENDOR does not
112a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  # exist.
113a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  if not os.path.exists(os.path.join(OPTIONS.input_tmp, "vendor")):
114a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    if os.path.exists(os.path.join(OPTIONS.input_tmp, "VENDOR")):
115a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      os.symlink(os.path.join(OPTIONS.input_tmp, "VENDOR"),
116a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang                 os.path.join(OPTIONS.input_tmp, "vendor"))
117a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    else:
118a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang      os.mkdir(os.path.join(OPTIONS.input_tmp, "vendor"))
119a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
120a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img = tempfile.NamedTemporaryFile()
121a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
122a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  fstab = OPTIONS.info_dict["fstab"]
123a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  if fstab:
124a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    image_props["fs_type" ] = fstab["/vendor"].fs_type
125a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  succ = build_image.BuildImage(os.path.join(OPTIONS.input_tmp, "vendor"),
126a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang                                image_props, img.name)
127a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  assert succ, "build vendor.img image failed"
128a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
129a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  common.CheckSize(img.name, "vendor.img", OPTIONS.info_dict)
130a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  output_zip.write(img.name, "vendor.img")
131a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang  img.close()
132a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
133a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang
134eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef AddUserdata(output_zip):
135eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  """Create an empty userdata image and store it in output_zip."""
136eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
1374e3f44f3564ff609a3075a863a132a84c22d308eYing Wang  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
1384e3f44f3564ff609a3075a863a132a84c22d308eYing Wang                                                    "data")
139d7321d31accd344f4f2ad0a8e0b4f47be4d5128eYing Wang  # If no userdata_size is provided for extfs, skip userdata.img.
140d7321d31accd344f4f2ad0a8e0b4f47be4d5128eYing Wang  if (image_props.get("fs_type", "").startswith("ext") and
141d7321d31accd344f4f2ad0a8e0b4f47be4d5128eYing Wang      not image_props.get("partition_size")):
1424e3f44f3564ff609a3075a863a132a84c22d308eYing Wang    return
1434e3f44f3564ff609a3075a863a132a84c22d308eYing Wang
144eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  print "creating userdata.img..."
145eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
146eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  # The name of the directory it is making an image out of matters to
147eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  # mkyaffs2image.  So we create a temp dir, and within it we create an
148eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  # empty dir named "data", and build the image from that.
149eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  temp_dir = tempfile.mkdtemp()
150eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  user_dir = os.path.join(temp_dir, "data")
151eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  os.mkdir(user_dir)
152eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  img = tempfile.NamedTemporaryFile()
153eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
15433a4b08b151d2dedd67f41a4b25b297163795628Doug Zongker  fstab = OPTIONS.info_dict["fstab"]
155bd93d425aedef907d8fef643b748897e9c7dceebYing Wang  if fstab:
156bd93d425aedef907d8fef643b748897e9c7dceebYing Wang    image_props["fs_type" ] = fstab["/data"].fs_type
157bd93d425aedef907d8fef643b748897e9c7dceebYing Wang  succ = build_image.BuildImage(user_dir, image_props, img.name)
158bd93d425aedef907d8fef643b748897e9c7dceebYing Wang  assert succ, "build userdata.img image failed"
159eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
16037974731fcb4e32b1de5f213d34bd832ca889869Doug Zongker  common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
161eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  output_zip.write(img.name, "userdata.img")
162eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  img.close()
163eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  os.rmdir(user_dir)
164eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  os.rmdir(temp_dir)
165eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
166eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
1679f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wangdef AddCache(output_zip):
1689f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  """Create an empty cache image and store it in output_zip."""
1699f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1709f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  image_props = build_image.ImagePropFromGlobalDict(OPTIONS.info_dict,
1719f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang                                                    "cache")
1729f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  # The build system has to explicitly request for cache.img.
1739f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  if "fs_type" not in image_props:
1749f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang    return
1759f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1769f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  print "creating cache.img..."
1779f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1789f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  # The name of the directory it is making an image out of matters to
1799f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  # mkyaffs2image.  So we create a temp dir, and within it we create an
1809f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  # empty dir named "cache", and build the image from that.
1819f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  temp_dir = tempfile.mkdtemp()
1829f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  user_dir = os.path.join(temp_dir, "cache")
1839f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  os.mkdir(user_dir)
1849f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  img = tempfile.NamedTemporaryFile()
1859f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1869f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  fstab = OPTIONS.info_dict["fstab"]
1879f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  if fstab:
1889f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang    image_props["fs_type" ] = fstab["/cache"].fs_type
1899f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  succ = build_image.BuildImage(user_dir, image_props, img.name)
1909f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  assert succ, "build cache.img image failed"
1919f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1929f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
1939f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  output_zip.write(img.name, "cache.img")
1949f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  img.close()
1959f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  os.rmdir(user_dir)
1969f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang  os.rmdir(temp_dir)
1979f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
1989f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang
199eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef CopyInfo(output_zip):
200eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  """Copy the android-info.txt file from the input to the output."""
201eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
202eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker                   "android-info.txt")
203eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
204eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
205eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerdef main(argv):
20655d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  bootable_only = [False]
207eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
208eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  def option_handler(o, a):
209eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    if o in ("-b", "--board_config"):
210fdd8e69c42e66fb70384bcaca1747f504f2c021cDoug Zongker      pass       # deprecated
21155d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker    if o in ("-z", "--bootable_zip"):
21255d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      bootable_only[0] = True
213eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    else:
214eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker      return False
215fdd8e69c42e66fb70384bcaca1747f504f2c021cDoug Zongker    return True
216eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
217eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  args = common.ParseOptions(argv, __doc__,
21855d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker                             extra_opts="b:z",
21955d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker                             extra_long_opts=["board_config=",
22055d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker                                              "bootable_zip"],
221eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker                             extra_option_handler=option_handler)
222eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
22355d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  bootable_only = bootable_only[0]
22455d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker
225eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  if len(args) != 2:
226eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    common.Usage(__doc__)
227eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    sys.exit(1)
228eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
22955d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
23037974731fcb4e32b1de5f213d34bd832ca889869Doug Zongker  OPTIONS.info_dict = common.LoadInfoDict(input_zip)
231d421f57d22009e4d9ce71298c2f93636ff9e7d9dYing Wang
232e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root  # If this image was originally labelled with SELinux contexts, make sure we
233e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root  # also apply the labels in our new image. During building, the "file_contexts"
234e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root  # is in the out/ directory tree, but for repacking from target-files.zip it's
235e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root  # in the root directory of the ramdisk.
236e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root  if "selinux_fc" in OPTIONS.info_dict:
237e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root    OPTIONS.info_dict["selinux_fc"] = os.path.join(OPTIONS.input_tmp, "BOOT", "RAMDISK",
238e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root        "file_contexts")
239e2e9f613b5259313c5216d4dad719998a2fbf014Kenny Root
240eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  output_zip = zipfile.ZipFile(args[1], "w", compression=zipfile.ZIP_DEFLATED)
241eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
24255d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  common.GetBootableImage(
24355d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT").AddToZip(output_zip)
24455d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  common.GetBootableImage(
24555d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      "recovery.img", "recovery.img", OPTIONS.input_tmp,
24655d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker      "RECOVERY").AddToZip(output_zip)
24755d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker
24855d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker  if not bootable_only:
24955d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker    AddSystem(output_zip)
250a0febe5e6de24ffee5cd32944d5a1814cf312efbYing Wang    AddVendor(output_zip)
25155d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker    AddUserdata(output_zip)
2529f8e8db188371cb3787a91a03d193f87ad244ea3Ying Wang    AddCache(output_zip)
25355d932840f1a5b412f2961f79368ecec2d28f647Doug Zongker    CopyInfo(output_zip)
254eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
255eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  print "cleaning up..."
256eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  output_zip.close()
257eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  shutil.rmtree(OPTIONS.input_tmp)
258eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
259eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  print "done."
260eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
261eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker
262eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongkerif __name__ == '__main__':
263eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  try:
2647e6d4e45d92fd51f42812ae63ac6e532887bfe0aYing Wang    common.CloseInheritedPipes()
265eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    main(sys.argv[1:])
266eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker  except common.ExternalError, e:
267eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    print
268eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    print "   ERROR: %s" % (e,)
269eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    print
270eef3944eb3673329b5e89cf188ac592805a0b08dDoug Zongker    sys.exit(1)
271