blob: 85b8a50941ab08f886b981a9f5489679ab130958 [file] [log] [blame]
Mike Frysingerc7f15932013-03-20 13:43:35 -04001#!/usr/bin/python
asharif252df0f2013-02-15 04:46:28 +00002#
3# Copyright 2010 Google Inc. All Rights Reserved.
4
5"""Script to enter the ChromeOS chroot with mounted sources.
6
7This script enters the chroot with mounted sources.
8"""
9
10__author__ = "asharif@google.com (Ahmad Sharif)"
11
12import getpass
13import optparse
14import os
asharif556f4ff2013-02-15 04:50:35 +000015import pwd
asharifc0f71932013-02-15 04:56:18 +000016import stat
asharif252df0f2013-02-15 04:46:28 +000017import sys
kbaclawski20082a02013-02-16 02:12:57 +000018
raymes01959ae2013-02-15 04:50:07 +000019from utils import command_executer
20from utils import logger
kbaclawski20082a02013-02-16 02:12:57 +000021from utils import misc
22
asharif252df0f2013-02-15 04:46:28 +000023
asharifda9ac652013-02-15 04:50:09 +000024class MountPoint:
25 def __init__(self, external_dir, mount_dir, owner, options=None):
asharif6c619132013-02-15 21:55:28 +000026 self.external_dir = os.path.realpath(external_dir)
27 self.mount_dir = os.path.realpath(mount_dir)
asharifda9ac652013-02-15 04:50:09 +000028 self.owner = owner
29 self.options = options
30
31
asharif556f4ff2013-02-15 04:50:35 +000032 def CreateAndOwnDir(self, dir_name):
33 retval = 0
34 if not os.path.exists(dir_name):
35 command = "mkdir -p " + dir_name
36 command += " || sudo mkdir -p " + dir_name
asharif8a873872013-02-15 04:56:52 +000037 retval = command_executer.GetCommandExecuter().RunCommand(command)
asharif556f4ff2013-02-15 04:50:35 +000038 if retval != 0:
39 return retval
40 pw = pwd.getpwnam(self.owner)
41 if os.stat(dir_name).st_uid != pw.pw_uid:
42 command = "sudo chown -f " + self.owner + " " + dir_name
asharif8a873872013-02-15 04:56:52 +000043 retval = command_executer.GetCommandExecuter().RunCommand(command)
asharifda9ac652013-02-15 04:50:09 +000044 return retval
45
46
47 def DoMount(self):
asharif6c619132013-02-15 21:55:28 +000048 ce = command_executer.GetCommandExecuter()
49 mount_signature = "%s on %s" % (self.external_dir, self.mount_dir)
50 command = "mount"
51 retval, out, err = ce.RunCommand(command, return_output=True)
52 if mount_signature not in out:
53 retval = self.CreateAndOwnDir(self.mount_dir)
54 logger.GetLogger().LogFatalIf(retval, "Cannot create mount_dir!")
55 retval = self.CreateAndOwnDir(self.external_dir)
56 logger.GetLogger().LogFatalIf(retval, "Cannot create external_dir!")
57 retval = self.MountDir()
58 logger.GetLogger().LogFatalIf(retval, "Cannot mount!")
59 return retval
60 else:
61 return 0
asharifda9ac652013-02-15 04:50:09 +000062
63
asharifc97199a2013-02-15 22:48:45 +000064 def UnMount(self):
65 ce = command_executer.GetCommandExecuter()
cmtice0186f572013-02-15 23:44:51 +000066 return ce.RunCommand("sudo umount %s" % self.mount_dir)
asharifc97199a2013-02-15 22:48:45 +000067
68
asharifda9ac652013-02-15 04:50:09 +000069 def MountDir(self):
70 command = "sudo mount --bind " + self.external_dir + " " + self.mount_dir
71 if self.options == "ro":
72 command += " && sudo mount --bind -oremount,ro " + self.mount_dir
asharif8a873872013-02-15 04:56:52 +000073 retval = command_executer.GetCommandExecuter().RunCommand(command)
asharifda9ac652013-02-15 04:50:09 +000074 return retval
75
76
77 def __str__(self):
78 ret = ""
79 ret += self.external_dir + "\n"
80 ret += self.mount_dir + "\n"
81 if self.owner:
82 ret += self.owner + "\n"
83 if self.options:
84 ret += self.options + "\n"
85 return ret
86
87
88def Main(argv, return_output=False):
asharif252df0f2013-02-15 04:46:28 +000089 """The main function."""
90 parser = optparse.OptionParser()
91 parser.add_option("-c", "--chromeos_root", dest="chromeos_root",
asharif0b2f0402013-02-15 04:50:25 +000092 default="../..",
asharif252df0f2013-02-15 04:46:28 +000093 help="ChromeOS root checkout directory.")
94 parser.add_option("-t", "--toolchain_root", dest="toolchain_root",
95 help="Toolchain root directory.")
asharif541b6392013-02-15 04:50:38 +000096 parser.add_option("-o", "--output", dest="output",
97 help="Toolchain output directory")
asharif52284c62013-02-15 19:59:08 +000098 parser.add_option("--sudo", dest="sudo",
99 action="store_true",
100 default=False,
101 help="Run the command with sudo.")
asharif8697d4e2013-02-15 09:18:09 +0000102 parser.add_option("-r", "--third_party", dest="third_party",
103 help="The third_party directory to mount.")
asharif541b6392013-02-15 04:50:38 +0000104 parser.add_option("-m", "--other_mounts", dest="other_mounts",
raymesa7d219c2013-02-15 04:56:23 +0000105 help="Other mount points in the form: " +
asharifda9ac652013-02-15 04:50:09 +0000106 "dir:mounted_dir:options")
asharif1755b432013-02-15 04:55:29 +0000107 parser.add_option("-s", "--mount-scripts-only",
108 dest="mount_scripts_only",
109 action="store_true",
110 default=False,
111 help="Mount only the scripts dir, and not the sources.")
asharif252df0f2013-02-15 04:46:28 +0000112
raymes01959ae2013-02-15 04:50:07 +0000113 passthrough_argv = []
asharif1755b432013-02-15 04:55:29 +0000114 (options, passthrough_argv) = parser.parse_args(argv)
asharif252df0f2013-02-15 04:46:28 +0000115
asharif0b2f0402013-02-15 04:50:25 +0000116 chromeos_root = options.chromeos_root
asharif17621302013-02-15 04:46:35 +0000117
118 chromeos_root = os.path.expanduser(chromeos_root)
asharifda9ac652013-02-15 04:50:09 +0000119 if options.toolchain_root:
120 options.toolchain_root = os.path.expanduser(options.toolchain_root)
asharif17621302013-02-15 04:46:35 +0000121
asharif252df0f2013-02-15 04:46:28 +0000122 chromeos_root = os.path.abspath(chromeos_root)
123
asharif8697d4e2013-02-15 09:18:09 +0000124 tc_dirs = []
asharif642509c2013-02-15 09:19:32 +0000125 if options.toolchain_root is None or options.mount_scripts_only:
asharif8697d4e2013-02-15 09:18:09 +0000126 m = "toolchain_root not specified. Will not mount toolchain dirs."
127 logger.GetLogger().LogWarning(m)
128 else:
129 tc_dirs = [options.toolchain_root + "/google_vendor_src_branch/gcc",
130 options.toolchain_root + "/google_vendor_src_branch/binutils"]
asharif252df0f2013-02-15 04:46:28 +0000131
asharif8697d4e2013-02-15 09:18:09 +0000132 for tc_dir in tc_dirs:
133 if not os.path.exists(tc_dir):
134 logger.GetLogger().LogError("toolchain path " +
135 tc_dir + " does not exist!")
136 parser.print_help()
137 sys.exit(1)
asharif0b2f0402013-02-15 04:50:25 +0000138
139 if not os.path.exists(chromeos_root):
140 logger.GetLogger().LogError("chromeos_root " + options.chromeos_root +
141 " does not exist!")
142 parser.print_help()
143 sys.exit(1)
144
asharifc8e8e122013-02-15 21:19:59 +0000145 if not os.path.exists(chromeos_root + "/src/scripts/build_packages"):
raymesa7d219c2013-02-15 04:56:23 +0000146 logger.GetLogger().LogError(options.chromeos_root +
asharifc8e8e122013-02-15 21:19:59 +0000147 "/src/scripts/build_packages"
asharif0b2f0402013-02-15 04:50:25 +0000148 " not found!")
149 parser.print_help()
150 sys.exit(1)
151
asharifb225e792013-02-15 21:20:11 +0000152 version_dir = os.path.realpath(os.path.expanduser(os.path.dirname(__file__)))
asharif252df0f2013-02-15 04:46:28 +0000153
asharif252df0f2013-02-15 04:46:28 +0000154 mounted_tc_root = "/usr/local/toolchain_root"
155 full_mounted_tc_root = chromeos_root + "/chroot/" + mounted_tc_root
156 full_mounted_tc_root = os.path.abspath(full_mounted_tc_root)
raymesa7d219c2013-02-15 04:56:23 +0000157
asharifda9ac652013-02-15 04:50:09 +0000158 mount_points = []
asharif8697d4e2013-02-15 09:18:09 +0000159 for tc_dir in tc_dirs:
kbaclawski20082a02013-02-16 02:12:57 +0000160 last_dir = misc.GetRoot(tc_dir)[1]
asharif8697d4e2013-02-15 09:18:09 +0000161 mount_point = MountPoint(tc_dir, full_mounted_tc_root + "/" + last_dir,
162 getpass.getuser(), "ro")
163 mount_points.append(mount_point)
asharif252df0f2013-02-15 04:46:28 +0000164
asharif8697d4e2013-02-15 09:18:09 +0000165 # Add the third_party mount point if it exists
166 if options.third_party:
167 third_party_dir = options.third_party
kbaclawski6999ada2013-02-15 19:57:09 +0000168 logger.GetLogger().LogFatalIf(not os.path.isdir(third_party_dir),
169 "--third_party option is not a valid dir.")
asharif8697d4e2013-02-15 09:18:09 +0000170 else:
171 third_party_dir = os.path.abspath("%s/../../../third_party" %
172 os.path.dirname(__file__))
173
174 if os.path.isdir(third_party_dir):
175 mount_point = MountPoint(third_party_dir,
176 ("%s/%s" %
177 (full_mounted_tc_root,
178 os.path.basename(third_party_dir))),
179 getpass.getuser())
180 mount_points.append(mount_point)
kbaclawski6999ada2013-02-15 19:57:09 +0000181
asharif541b6392013-02-15 04:50:38 +0000182 output = options.output
asharif8697d4e2013-02-15 09:18:09 +0000183 if output is None and options.toolchain_root:
asharif8697d4e2013-02-15 09:18:09 +0000184 # Mount the output directory at /usr/local/toolchain_root/output
asharif01410cc2013-02-15 09:19:31 +0000185 output = options.toolchain_root + "/output"
186
187 if output:
asharif8697d4e2013-02-15 09:18:09 +0000188 mount_points.append(MountPoint(output, full_mounted_tc_root + "/output",
189 getpass.getuser()))
190
191 # Mount the other mount points
raymesa7d219c2013-02-15 04:56:23 +0000192 mount_points += CreateMountPointsFromString(options.other_mounts,
asharifda9ac652013-02-15 04:50:09 +0000193 chromeos_root + "/chroot/")
194
kbaclawski20082a02013-02-16 02:12:57 +0000195 last_dir = misc.GetRoot(version_dir)[1]
asharif8697d4e2013-02-15 09:18:09 +0000196
197 # Mount the version dir (v14) at /usr/local/toolchain_root/v14
asharifda9ac652013-02-15 04:50:09 +0000198 mount_point = MountPoint(version_dir, full_mounted_tc_root + "/" + last_dir,
199 getpass.getuser())
200 mount_points.append(mount_point)
201
202 for mount_point in mount_points:
asharif556f4ff2013-02-15 04:50:35 +0000203 retval = mount_point.DoMount()
204 if retval != 0:
205 return retval
asharif252df0f2013-02-15 04:46:28 +0000206
207 # Finally, create the symlink to build-gcc.
asharifda9ac652013-02-15 04:50:09 +0000208 command = "sudo chown " + getpass.getuser() + " " + full_mounted_tc_root
asharif8a873872013-02-15 04:56:52 +0000209 retval = command_executer.GetCommandExecuter().RunCommand(command)
asharifda9ac652013-02-15 04:50:09 +0000210
asharif252df0f2013-02-15 04:46:28 +0000211 try:
asharif8a873872013-02-15 04:56:52 +0000212 CreateSymlink(last_dir + "/build-gcc", full_mounted_tc_root + "/build-gcc")
213 CreateSymlink(last_dir + "/build-binutils", full_mounted_tc_root + "/build-binutils")
asharif252df0f2013-02-15 04:46:28 +0000214 except Exception as e:
asharif0b2f0402013-02-15 04:50:25 +0000215 logger.GetLogger().LogError(str(e))
asharif252df0f2013-02-15 04:46:28 +0000216
asharif36666532013-02-15 21:08:14 +0000217 # Now call cros_sdk --enter with the rest of the arguments.
218 command = "cd %s/src/scripts && cros_sdk --enter" % chromeos_root
asharif252df0f2013-02-15 04:46:28 +0000219
asharif0269d462013-02-15 04:46:31 +0000220 if len(passthrough_argv) > 1:
asharif51516da2013-02-15 04:56:12 +0000221 inner_command = " ".join(passthrough_argv[1:])
222 inner_command = inner_command.strip()
223 if inner_command.startswith("-- "):
224 inner_command = inner_command[3:]
asharifc0f71932013-02-15 04:56:18 +0000225 command_file = "tc_enter_chroot.cmd"
226 command_file_path = chromeos_root + "/src/scripts/" + command_file
asharif8a873872013-02-15 04:56:52 +0000227 retval = command_executer.GetCommandExecuter().RunCommand("sudo rm -f " + command_file_path)
asharifc0f71932013-02-15 04:56:18 +0000228 if retval != 0:
229 return retval
230 f = open(command_file_path, "w")
231 f.write(inner_command)
232 f.close()
raymesa7d219c2013-02-15 04:56:23 +0000233 logger.GetLogger().LogCmd(inner_command)
asharif8a873872013-02-15 04:56:52 +0000234 retval = command_executer.GetCommandExecuter().RunCommand("chmod +x " + command_file_path)
asharifc0f71932013-02-15 04:56:18 +0000235 if retval != 0:
236 return retval
asharif52284c62013-02-15 19:59:08 +0000237
238 if options.sudo:
239 command += " sudo ./" + command_file
240 else:
241 command += " ./" + command_file
asharif8a873872013-02-15 04:56:52 +0000242 retval = command_executer.GetCommandExecuter().RunCommand(command, return_output)
asharif252df0f2013-02-15 04:46:28 +0000243 return retval
244 else:
asharif36666532013-02-15 21:08:14 +0000245 os.chdir("%s/src/scripts" % chromeos_root)
246 ce = command_executer.GetCommandExecuter()
247 [ret, out, err] = ce.RunCommand("which cros_sdk", return_output=True)
248 cros_sdk_binary = out.split()[0]
249 return os.execv(cros_sdk_binary, ["", "--enter"])
asharif252df0f2013-02-15 04:46:28 +0000250
251
asharifda9ac652013-02-15 04:50:09 +0000252def CreateMountPointsFromString(mount_strings, chroot_dir):
253 # String has options in the form dir:mount:options
254 mount_points = []
255 if not mount_strings:
256 return mount_points
257 mount_list = mount_strings.split()
258 for mount_string in mount_list:
259 mount_values = mount_string.split(":")
260 external_dir = mount_values[0]
261 mount_dir = mount_values[1]
raymesa7d219c2013-02-15 04:56:23 +0000262 if len(mount_values) > 2:
asharifda9ac652013-02-15 04:50:09 +0000263 options = mount_values[2]
264 else:
265 options = None
raymesa7d219c2013-02-15 04:56:23 +0000266 mount_point = MountPoint(external_dir, chroot_dir + "/" + mount_dir,
asharifda9ac652013-02-15 04:50:09 +0000267 getpass.getuser(), options)
268 mount_points.append(mount_point)
269 return mount_points
asharif252df0f2013-02-15 04:46:28 +0000270
271
asharif8a873872013-02-15 04:56:52 +0000272def CreateSymlink(target, link_name):
kbaclawski6999ada2013-02-15 19:57:09 +0000273 logger.GetLogger().LogFatalIf(target.startswith("/"),
274 "Can't create symlink to absolute path!")
kbaclawski20082a02013-02-16 02:12:57 +0000275 real_from_file = misc.GetRoot(link_name)[0] + "/" + target
asharif8a873872013-02-15 04:56:52 +0000276 if os.path.realpath(real_from_file) != os.path.realpath(link_name):
277 if os.path.exists(link_name):
278 command = "rm -rf " + link_name
279 command_executer.GetCommandExecuter().RunCommand(command)
280 os.symlink(target, link_name)
281
282
asharif252df0f2013-02-15 04:46:28 +0000283if __name__ == "__main__":
asharif2198c512013-02-15 09:21:35 +0000284 retval = Main(sys.argv)
285 sys.exit(retval)