blob: 3a7538ad63b91ec8cebe7599eb55fe8582e57afe [file] [log] [blame]
Zhizhou Yang81d651f2020-02-10 16:51:20 -08001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright 2010 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
asharif252df0f2013-02-15 04:46:28 +00007"""Script to enter the ChromeOS chroot with mounted sources.
8
9This script enters the chroot with mounted sources.
10"""
11
Caroline Tice88272d42016-01-13 09:48:29 -080012from __future__ import print_function
13
Luis Lozanof2a3ef42015-12-15 13:49:30 -080014__author__ = 'asharif@google.com (Ahmad Sharif)'
asharif252df0f2013-02-15 04:46:28 +000015
Caroline Tice88272d42016-01-13 09:48:29 -080016import argparse
asharif252df0f2013-02-15 04:46:28 +000017import getpass
asharif252df0f2013-02-15 04:46:28 +000018import os
asharif556f4ff2013-02-15 04:50:35 +000019import pwd
asharif252df0f2013-02-15 04:46:28 +000020import sys
kbaclawski20082a02013-02-16 02:12:57 +000021
Caroline Tice88272d42016-01-13 09:48:29 -080022from cros_utils import command_executer
23from cros_utils import logger
24from cros_utils import misc
kbaclawski20082a02013-02-16 02:12:57 +000025
asharif252df0f2013-02-15 04:46:28 +000026
Caroline Tice88272d42016-01-13 09:48:29 -080027class MountPoint(object):
28 """Mount point class"""
Luis Lozanof2a3ef42015-12-15 13:49:30 -080029
asharifda9ac652013-02-15 04:50:09 +000030 def __init__(self, external_dir, mount_dir, owner, options=None):
asharif6c619132013-02-15 21:55:28 +000031 self.external_dir = os.path.realpath(external_dir)
32 self.mount_dir = os.path.realpath(mount_dir)
asharifda9ac652013-02-15 04:50:09 +000033 self.owner = owner
34 self.options = options
35
asharif556f4ff2013-02-15 04:50:35 +000036 def CreateAndOwnDir(self, dir_name):
Caroline Tice88272d42016-01-13 09:48:29 -080037 retv = 0
asharif556f4ff2013-02-15 04:50:35 +000038 if not os.path.exists(dir_name):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080039 command = 'mkdir -p ' + dir_name
40 command += ' || sudo mkdir -p ' + dir_name
Caroline Tice88272d42016-01-13 09:48:29 -080041 retv = command_executer.GetCommandExecuter().RunCommand(command)
42 if retv != 0:
43 return retv
asharif556f4ff2013-02-15 04:50:35 +000044 pw = pwd.getpwnam(self.owner)
45 if os.stat(dir_name).st_uid != pw.pw_uid:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080046 command = 'sudo chown -f ' + self.owner + ' ' + dir_name
Caroline Tice88272d42016-01-13 09:48:29 -080047 retv = command_executer.GetCommandExecuter().RunCommand(command)
48 return retv
asharifda9ac652013-02-15 04:50:09 +000049
asharifda9ac652013-02-15 04:50:09 +000050 def DoMount(self):
asharif6c619132013-02-15 21:55:28 +000051 ce = command_executer.GetCommandExecuter()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080052 mount_signature = '%s on %s' % (self.external_dir, self.mount_dir)
53 command = 'mount'
Caroline Tice88272d42016-01-13 09:48:29 -080054 retv, out, _ = ce.RunCommandWOutput(command)
asharif6c619132013-02-15 21:55:28 +000055 if mount_signature not in out:
Caroline Tice88272d42016-01-13 09:48:29 -080056 retv = self.CreateAndOwnDir(self.mount_dir)
57 logger.GetLogger().LogFatalIf(retv, 'Cannot create mount_dir!')
58 retv = self.CreateAndOwnDir(self.external_dir)
59 logger.GetLogger().LogFatalIf(retv, 'Cannot create external_dir!')
60 retv = self.MountDir()
61 logger.GetLogger().LogFatalIf(retv, 'Cannot mount!')
62 return retv
asharif6c619132013-02-15 21:55:28 +000063 else:
64 return 0
asharifda9ac652013-02-15 04:50:09 +000065
asharifc97199a2013-02-15 22:48:45 +000066 def UnMount(self):
67 ce = command_executer.GetCommandExecuter()
Luis Lozanof2a3ef42015-12-15 13:49:30 -080068 return ce.RunCommand('sudo umount %s' % self.mount_dir)
asharifc97199a2013-02-15 22:48:45 +000069
asharifda9ac652013-02-15 04:50:09 +000070 def MountDir(self):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080071 command = 'sudo mount --bind ' + self.external_dir + ' ' + self.mount_dir
72 if self.options == 'ro':
73 command += ' && sudo mount --bind -oremount,ro ' + self.mount_dir
Caroline Tice88272d42016-01-13 09:48:29 -080074 retv = command_executer.GetCommandExecuter().RunCommand(command)
75 return retv
asharifda9ac652013-02-15 04:50:09 +000076
asharifda9ac652013-02-15 04:50:09 +000077 def __str__(self):
Luis Lozanof2a3ef42015-12-15 13:49:30 -080078 ret = ''
79 ret += self.external_dir + '\n'
80 ret += self.mount_dir + '\n'
asharifda9ac652013-02-15 04:50:09 +000081 if self.owner:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080082 ret += self.owner + '\n'
asharifda9ac652013-02-15 04:50:09 +000083 if self.options:
Luis Lozanof2a3ef42015-12-15 13:49:30 -080084 ret += self.options + '\n'
asharifda9ac652013-02-15 04:50:09 +000085 return ret
86
87
88def Main(argv, return_output=False):
asharif252df0f2013-02-15 04:46:28 +000089 """The main function."""
asharif252df0f2013-02-15 04:46:28 +000090
Caroline Tice88272d42016-01-13 09:48:29 -080091 parser = argparse.ArgumentParser()
Caroline Ticef6ef4392017-04-06 17:16:05 -070092 parser.add_argument(
93 '-c',
94 '--chromeos_root',
95 dest='chromeos_root',
96 default='../..',
97 help='ChromeOS root checkout directory.')
98 parser.add_argument(
99 '-t',
100 '--toolchain_root',
101 dest='toolchain_root',
102 help='Toolchain root directory.')
103 parser.add_argument(
104 '-o', '--output', dest='output', help='Toolchain output directory')
105 parser.add_argument(
106 '--sudo',
107 dest='sudo',
108 action='store_true',
109 default=False,
110 help='Run the command with sudo.')
111 parser.add_argument(
112 '-r',
113 '--third_party',
114 dest='third_party',
115 help='The third_party directory to mount.')
116 parser.add_argument(
117 '-m',
118 '--other_mounts',
119 dest='other_mounts',
120 help='Other mount points in the form: '
121 'dir:mounted_dir:options')
122 parser.add_argument(
123 '-s',
124 '--mount-scripts-only',
125 dest='mount_scripts_only',
126 action='store_true',
127 default=False,
128 help='Mount only the scripts dir, and not the sources.')
129 parser.add_argument(
130 'passthrough_argv',
131 nargs='*',
132 help='Command to be executed inside the chroot.')
Caroline Tice88272d42016-01-13 09:48:29 -0800133
134 options = parser.parse_args(argv)
asharif252df0f2013-02-15 04:46:28 +0000135
asharif0b2f0402013-02-15 04:50:25 +0000136 chromeos_root = options.chromeos_root
asharif17621302013-02-15 04:46:35 +0000137
138 chromeos_root = os.path.expanduser(chromeos_root)
asharifda9ac652013-02-15 04:50:09 +0000139 if options.toolchain_root:
140 options.toolchain_root = os.path.expanduser(options.toolchain_root)
asharif17621302013-02-15 04:46:35 +0000141
asharif252df0f2013-02-15 04:46:28 +0000142 chromeos_root = os.path.abspath(chromeos_root)
143
asharif8697d4e2013-02-15 09:18:09 +0000144 tc_dirs = []
asharif642509c2013-02-15 09:19:32 +0000145 if options.toolchain_root is None or options.mount_scripts_only:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800146 m = 'toolchain_root not specified. Will not mount toolchain dirs.'
asharif8697d4e2013-02-15 09:18:09 +0000147 logger.GetLogger().LogWarning(m)
148 else:
Caroline Ticef6ef4392017-04-06 17:16:05 -0700149 tc_dirs = [
150 options.toolchain_root + '/google_vendor_src_branch/gcc',
151 options.toolchain_root + '/google_vendor_src_branch/binutils'
152 ]
asharif252df0f2013-02-15 04:46:28 +0000153
asharif8697d4e2013-02-15 09:18:09 +0000154 for tc_dir in tc_dirs:
155 if not os.path.exists(tc_dir):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800156 logger.GetLogger().LogError('toolchain path ' + tc_dir +
157 ' does not exist!')
asharif8697d4e2013-02-15 09:18:09 +0000158 parser.print_help()
159 sys.exit(1)
asharif0b2f0402013-02-15 04:50:25 +0000160
161 if not os.path.exists(chromeos_root):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800162 logger.GetLogger().LogError('chromeos_root ' + options.chromeos_root +
163 ' does not exist!')
asharif0b2f0402013-02-15 04:50:25 +0000164 parser.print_help()
165 sys.exit(1)
166
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800167 if not os.path.exists(chromeos_root + '/src/scripts/build_packages'):
Caroline Ticef6ef4392017-04-06 17:16:05 -0700168 logger.GetLogger().LogError(options.chromeos_root +
169 '/src/scripts/build_packages'
170 ' not found!')
asharif0b2f0402013-02-15 04:50:25 +0000171 parser.print_help()
172 sys.exit(1)
173
asharifb225e792013-02-15 21:20:11 +0000174 version_dir = os.path.realpath(os.path.expanduser(os.path.dirname(__file__)))
asharif252df0f2013-02-15 04:46:28 +0000175
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800176 mounted_tc_root = '/usr/local/toolchain_root'
177 full_mounted_tc_root = chromeos_root + '/chroot/' + mounted_tc_root
asharif252df0f2013-02-15 04:46:28 +0000178 full_mounted_tc_root = os.path.abspath(full_mounted_tc_root)
raymesa7d219c2013-02-15 04:56:23 +0000179
asharifda9ac652013-02-15 04:50:09 +0000180 mount_points = []
asharif8697d4e2013-02-15 09:18:09 +0000181 for tc_dir in tc_dirs:
kbaclawski20082a02013-02-16 02:12:57 +0000182 last_dir = misc.GetRoot(tc_dir)[1]
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800183 mount_point = MountPoint(tc_dir, full_mounted_tc_root + '/' + last_dir,
184 getpass.getuser(), 'ro')
asharif8697d4e2013-02-15 09:18:09 +0000185 mount_points.append(mount_point)
asharif252df0f2013-02-15 04:46:28 +0000186
asharif8697d4e2013-02-15 09:18:09 +0000187 # Add the third_party mount point if it exists
188 if options.third_party:
189 third_party_dir = options.third_party
Caroline Ticef6ef4392017-04-06 17:16:05 -0700190 logger.GetLogger().LogFatalIf(not os.path.isdir(third_party_dir),
191 '--third_party option is not a valid dir.')
asharif8697d4e2013-02-15 09:18:09 +0000192 else:
Caroline Ticef6ef4392017-04-06 17:16:05 -0700193 third_party_dir = os.path.abspath(
194 '%s/../../../third_party' % os.path.dirname(__file__))
asharif8697d4e2013-02-15 09:18:09 +0000195
196 if os.path.isdir(third_party_dir):
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800197 mount_point = MountPoint(
198 third_party_dir,
199 ('%s/%s' % (full_mounted_tc_root, os.path.basename(third_party_dir))),
200 getpass.getuser())
asharif8697d4e2013-02-15 09:18:09 +0000201 mount_points.append(mount_point)
kbaclawski6999ada2013-02-15 19:57:09 +0000202
asharif541b6392013-02-15 04:50:38 +0000203 output = options.output
asharif8697d4e2013-02-15 09:18:09 +0000204 if output is None and options.toolchain_root:
asharif8697d4e2013-02-15 09:18:09 +0000205 # Mount the output directory at /usr/local/toolchain_root/output
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800206 output = options.toolchain_root + '/output'
asharif01410cc2013-02-15 09:19:31 +0000207
208 if output:
Caroline Ticef6ef4392017-04-06 17:16:05 -0700209 mount_points.append(
210 MountPoint(output, full_mounted_tc_root + '/output', getpass.getuser()))
asharif8697d4e2013-02-15 09:18:09 +0000211
212 # Mount the other mount points
raymesa7d219c2013-02-15 04:56:23 +0000213 mount_points += CreateMountPointsFromString(options.other_mounts,
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800214 chromeos_root + '/chroot/')
asharifda9ac652013-02-15 04:50:09 +0000215
kbaclawski20082a02013-02-16 02:12:57 +0000216 last_dir = misc.GetRoot(version_dir)[1]
asharif8697d4e2013-02-15 09:18:09 +0000217
218 # Mount the version dir (v14) at /usr/local/toolchain_root/v14
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800219 mount_point = MountPoint(version_dir, full_mounted_tc_root + '/' + last_dir,
asharifda9ac652013-02-15 04:50:09 +0000220 getpass.getuser())
221 mount_points.append(mount_point)
222
223 for mount_point in mount_points:
Caroline Tice88272d42016-01-13 09:48:29 -0800224 retv = mount_point.DoMount()
225 if retv != 0:
226 return retv
asharif252df0f2013-02-15 04:46:28 +0000227
228 # Finally, create the symlink to build-gcc.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800229 command = 'sudo chown ' + getpass.getuser() + ' ' + full_mounted_tc_root
Caroline Tice88272d42016-01-13 09:48:29 -0800230 retv = command_executer.GetCommandExecuter().RunCommand(command)
asharifda9ac652013-02-15 04:50:09 +0000231
asharif252df0f2013-02-15 04:46:28 +0000232 try:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800233 CreateSymlink(last_dir + '/build-gcc', full_mounted_tc_root + '/build-gcc')
234 CreateSymlink(last_dir + '/build-binutils',
235 full_mounted_tc_root + '/build-binutils')
asharif252df0f2013-02-15 04:46:28 +0000236 except Exception as e:
asharif0b2f0402013-02-15 04:50:25 +0000237 logger.GetLogger().LogError(str(e))
asharif252df0f2013-02-15 04:46:28 +0000238
asharif36666532013-02-15 21:08:14 +0000239 # Now call cros_sdk --enter with the rest of the arguments.
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800240 command = 'cd %s/src/scripts && cros_sdk --enter' % chromeos_root
asharif252df0f2013-02-15 04:46:28 +0000241
Caroline Tice88272d42016-01-13 09:48:29 -0800242 if len(options.passthrough_argv) > 1:
243 inner_command = ' '.join(options.passthrough_argv[1:])
asharif51516da2013-02-15 04:56:12 +0000244 inner_command = inner_command.strip()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800245 if inner_command.startswith('-- '):
asharif51516da2013-02-15 04:56:12 +0000246 inner_command = inner_command[3:]
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800247 command_file = 'tc_enter_chroot.cmd'
248 command_file_path = chromeos_root + '/src/scripts/' + command_file
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800249 retv = command_executer.GetCommandExecuter().RunCommand('sudo rm -f ' +
250 command_file_path)
Caroline Tice88272d42016-01-13 09:48:29 -0800251 if retv != 0:
252 return retv
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800253 with open(command_file_path, 'w', encoding='utf-8') as f:
254 f.write(inner_command)
raymesa7d219c2013-02-15 04:56:23 +0000255 logger.GetLogger().LogCmd(inner_command)
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800256 retv = command_executer.GetCommandExecuter().RunCommand('chmod +x ' +
257 command_file_path)
Caroline Tice88272d42016-01-13 09:48:29 -0800258 if retv != 0:
259 return retv
asharif52284c62013-02-15 19:59:08 +0000260
261 if options.sudo:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800262 command += ' sudo ./' + command_file
asharif52284c62013-02-15 19:59:08 +0000263 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800264 command += ' ./' + command_file
Caroline Tice88272d42016-01-13 09:48:29 -0800265 retv = command_executer.GetCommandExecuter().RunCommandGeneric(
Luis Lozano036c9232015-12-10 10:47:01 -0800266 command, return_output)
Caroline Tice88272d42016-01-13 09:48:29 -0800267 return retv
asharif252df0f2013-02-15 04:46:28 +0000268 else:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800269 os.chdir('%s/src/scripts' % chromeos_root)
asharif36666532013-02-15 21:08:14 +0000270 ce = command_executer.GetCommandExecuter()
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800271 _, out, _ = ce.RunCommandWOutput('which cros_sdk')
asharif36666532013-02-15 21:08:14 +0000272 cros_sdk_binary = out.split()[0]
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800273 return os.execv(cros_sdk_binary, ['', '--enter'])
asharif252df0f2013-02-15 04:46:28 +0000274
275
asharifda9ac652013-02-15 04:50:09 +0000276def CreateMountPointsFromString(mount_strings, chroot_dir):
277 # String has options in the form dir:mount:options
278 mount_points = []
279 if not mount_strings:
280 return mount_points
281 mount_list = mount_strings.split()
282 for mount_string in mount_list:
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800283 mount_values = mount_string.split(':')
asharifda9ac652013-02-15 04:50:09 +0000284 external_dir = mount_values[0]
285 mount_dir = mount_values[1]
raymesa7d219c2013-02-15 04:56:23 +0000286 if len(mount_values) > 2:
asharifda9ac652013-02-15 04:50:09 +0000287 options = mount_values[2]
288 else:
289 options = None
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800290 mount_point = MountPoint(external_dir, chroot_dir + '/' + mount_dir,
asharifda9ac652013-02-15 04:50:09 +0000291 getpass.getuser(), options)
292 mount_points.append(mount_point)
293 return mount_points
asharif252df0f2013-02-15 04:46:28 +0000294
295
asharif8a873872013-02-15 04:56:52 +0000296def CreateSymlink(target, link_name):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800297 logger.GetLogger().LogFatalIf(
298 target.startswith('/'), "Can't create symlink to absolute path!")
299 real_from_file = misc.GetRoot(link_name)[0] + '/' + target
asharif8a873872013-02-15 04:56:52 +0000300 if os.path.realpath(real_from_file) != os.path.realpath(link_name):
301 if os.path.exists(link_name):
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800302 command = 'rm -rf ' + link_name
asharif8a873872013-02-15 04:56:52 +0000303 command_executer.GetCommandExecuter().RunCommand(command)
304 os.symlink(target, link_name)
305
306
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800307if __name__ == '__main__':
asharif2198c512013-02-15 09:21:35 +0000308 retval = Main(sys.argv)
309 sys.exit(retval)