aboutsummaryrefslogtreecommitdiff
path: root/tc_enter_chroot.py
diff options
context:
space:
mode:
Diffstat (limited to 'tc_enter_chroot.py')
-rwxr-xr-xtc_enter_chroot.py299
1 files changed, 299 insertions, 0 deletions
diff --git a/tc_enter_chroot.py b/tc_enter_chroot.py
new file mode 100755
index 00000000..573e5585
--- /dev/null
+++ b/tc_enter_chroot.py
@@ -0,0 +1,299 @@
+#!/usr/bin/python2
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+"""Script to enter the ChromeOS chroot with mounted sources.
+
+This script enters the chroot with mounted sources.
+"""
+
+from __future__ import print_function
+
+__author__ = 'asharif@google.com (Ahmad Sharif)'
+
+import argparse
+import getpass
+import os
+import pwd
+import sys
+
+from cros_utils import command_executer
+from cros_utils import logger
+from cros_utils import misc
+
+
+class MountPoint(object):
+ """Mount point class"""
+
+ def __init__(self, external_dir, mount_dir, owner, options=None):
+ self.external_dir = os.path.realpath(external_dir)
+ self.mount_dir = os.path.realpath(mount_dir)
+ self.owner = owner
+ self.options = options
+
+ def CreateAndOwnDir(self, dir_name):
+ retv = 0
+ if not os.path.exists(dir_name):
+ command = 'mkdir -p ' + dir_name
+ command += ' || sudo mkdir -p ' + dir_name
+ retv = command_executer.GetCommandExecuter().RunCommand(command)
+ if retv != 0:
+ return retv
+ pw = pwd.getpwnam(self.owner)
+ if os.stat(dir_name).st_uid != pw.pw_uid:
+ command = 'sudo chown -f ' + self.owner + ' ' + dir_name
+ retv = command_executer.GetCommandExecuter().RunCommand(command)
+ return retv
+
+ def DoMount(self):
+ ce = command_executer.GetCommandExecuter()
+ mount_signature = '%s on %s' % (self.external_dir, self.mount_dir)
+ command = 'mount'
+ retv, out, _ = ce.RunCommandWOutput(command)
+ if mount_signature not in out:
+ retv = self.CreateAndOwnDir(self.mount_dir)
+ logger.GetLogger().LogFatalIf(retv, 'Cannot create mount_dir!')
+ retv = self.CreateAndOwnDir(self.external_dir)
+ logger.GetLogger().LogFatalIf(retv, 'Cannot create external_dir!')
+ retv = self.MountDir()
+ logger.GetLogger().LogFatalIf(retv, 'Cannot mount!')
+ return retv
+ else:
+ return 0
+
+ def UnMount(self):
+ ce = command_executer.GetCommandExecuter()
+ return ce.RunCommand('sudo umount %s' % self.mount_dir)
+
+ def MountDir(self):
+ command = 'sudo mount --bind ' + self.external_dir + ' ' + self.mount_dir
+ if self.options == 'ro':
+ command += ' && sudo mount --bind -oremount,ro ' + self.mount_dir
+ retv = command_executer.GetCommandExecuter().RunCommand(command)
+ return retv
+
+ def __str__(self):
+ ret = ''
+ ret += self.external_dir + '\n'
+ ret += self.mount_dir + '\n'
+ if self.owner:
+ ret += self.owner + '\n'
+ if self.options:
+ ret += self.options + '\n'
+ return ret
+
+
+def Main(argv, return_output=False):
+ """The main function."""
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-c',
+ '--chromeos_root',
+ dest='chromeos_root',
+ default='../..',
+ help='ChromeOS root checkout directory.')
+ parser.add_argument('-t',
+ '--toolchain_root',
+ dest='toolchain_root',
+ help='Toolchain root directory.')
+ parser.add_argument('-o',
+ '--output',
+ dest='output',
+ help='Toolchain output directory')
+ parser.add_argument('--sudo',
+ dest='sudo',
+ action='store_true',
+ default=False,
+ help='Run the command with sudo.')
+ parser.add_argument('-r',
+ '--third_party',
+ dest='third_party',
+ help='The third_party directory to mount.')
+ parser.add_argument('-m',
+ '--other_mounts',
+ dest='other_mounts',
+ help='Other mount points in the form: '
+ 'dir:mounted_dir:options')
+ parser.add_argument('-s',
+ '--mount-scripts-only',
+ dest='mount_scripts_only',
+ action='store_true',
+ default=False,
+ help='Mount only the scripts dir, and not the sources.')
+ parser.add_argument('passthrough_argv', nargs='*',
+ help='Command to be executed inside the chroot.')
+
+ options = parser.parse_args(argv)
+
+ chromeos_root = options.chromeos_root
+
+ chromeos_root = os.path.expanduser(chromeos_root)
+ if options.toolchain_root:
+ options.toolchain_root = os.path.expanduser(options.toolchain_root)
+
+ chromeos_root = os.path.abspath(chromeos_root)
+
+ tc_dirs = []
+ if options.toolchain_root is None or options.mount_scripts_only:
+ m = 'toolchain_root not specified. Will not mount toolchain dirs.'
+ logger.GetLogger().LogWarning(m)
+ else:
+ tc_dirs = [options.toolchain_root + '/google_vendor_src_branch/gcc',
+ options.toolchain_root + '/google_vendor_src_branch/binutils']
+
+ for tc_dir in tc_dirs:
+ if not os.path.exists(tc_dir):
+ logger.GetLogger().LogError('toolchain path ' + tc_dir +
+ ' does not exist!')
+ parser.print_help()
+ sys.exit(1)
+
+ if not os.path.exists(chromeos_root):
+ logger.GetLogger().LogError('chromeos_root ' + options.chromeos_root +
+ ' does not exist!')
+ parser.print_help()
+ sys.exit(1)
+
+ if not os.path.exists(chromeos_root + '/src/scripts/build_packages'):
+ logger.GetLogger(
+ ).LogError(options.chromeos_root + '/src/scripts/build_packages'
+ ' not found!')
+ parser.print_help()
+ sys.exit(1)
+
+ version_dir = os.path.realpath(os.path.expanduser(os.path.dirname(__file__)))
+
+ mounted_tc_root = '/usr/local/toolchain_root'
+ full_mounted_tc_root = chromeos_root + '/chroot/' + mounted_tc_root
+ full_mounted_tc_root = os.path.abspath(full_mounted_tc_root)
+
+ mount_points = []
+ for tc_dir in tc_dirs:
+ last_dir = misc.GetRoot(tc_dir)[1]
+ mount_point = MountPoint(tc_dir, full_mounted_tc_root + '/' + last_dir,
+ getpass.getuser(), 'ro')
+ mount_points.append(mount_point)
+
+ # Add the third_party mount point if it exists
+ if options.third_party:
+ third_party_dir = options.third_party
+ logger.GetLogger().LogFatalIf(
+ not os.path.isdir(third_party_dir),
+ '--third_party option is not a valid dir.')
+ else:
+ third_party_dir = os.path.abspath('%s/../../../third_party' %
+ os.path.dirname(__file__))
+
+ if os.path.isdir(third_party_dir):
+ mount_point = MountPoint(third_party_dir, ('%s/%s' % (
+ full_mounted_tc_root, os.path.basename(third_party_dir))),
+ getpass.getuser())
+ mount_points.append(mount_point)
+
+ output = options.output
+ if output is None and options.toolchain_root:
+ # Mount the output directory at /usr/local/toolchain_root/output
+ output = options.toolchain_root + '/output'
+
+ if output:
+ mount_points.append(MountPoint(output, full_mounted_tc_root + '/output',
+ getpass.getuser()))
+
+ # Mount the other mount points
+ mount_points += CreateMountPointsFromString(options.other_mounts,
+ chromeos_root + '/chroot/')
+
+ last_dir = misc.GetRoot(version_dir)[1]
+
+ # Mount the version dir (v14) at /usr/local/toolchain_root/v14
+ mount_point = MountPoint(version_dir, full_mounted_tc_root + '/' + last_dir,
+ getpass.getuser())
+ mount_points.append(mount_point)
+
+ for mount_point in mount_points:
+ retv = mount_point.DoMount()
+ if retv != 0:
+ return retv
+
+ # Finally, create the symlink to build-gcc.
+ command = 'sudo chown ' + getpass.getuser() + ' ' + full_mounted_tc_root
+ retv = command_executer.GetCommandExecuter().RunCommand(command)
+
+ try:
+ CreateSymlink(last_dir + '/build-gcc', full_mounted_tc_root + '/build-gcc')
+ CreateSymlink(last_dir + '/build-binutils',
+ full_mounted_tc_root + '/build-binutils')
+ except Exception as e:
+ logger.GetLogger().LogError(str(e))
+
+ # Now call cros_sdk --enter with the rest of the arguments.
+ command = 'cd %s/src/scripts && cros_sdk --enter' % chromeos_root
+
+ if len(options.passthrough_argv) > 1:
+ inner_command = ' '.join(options.passthrough_argv[1:])
+ inner_command = inner_command.strip()
+ if inner_command.startswith('-- '):
+ inner_command = inner_command[3:]
+ command_file = 'tc_enter_chroot.cmd'
+ command_file_path = chromeos_root + '/src/scripts/' + command_file
+ retv = command_executer.GetCommandExecuter().RunCommand('sudo rm -f ' +
+ command_file_path)
+ if retv != 0:
+ return retv
+ f = open(command_file_path, 'w')
+ f.write(inner_command)
+ f.close()
+ logger.GetLogger().LogCmd(inner_command)
+ retv = command_executer.GetCommandExecuter().RunCommand('chmod +x ' +
+ command_file_path)
+ if retv != 0:
+ return retv
+
+ if options.sudo:
+ command += ' sudo ./' + command_file
+ else:
+ command += ' ./' + command_file
+ retv = command_executer.GetCommandExecuter().RunCommandGeneric(
+ command, return_output)
+ return retv
+ else:
+ os.chdir('%s/src/scripts' % chromeos_root)
+ ce = command_executer.GetCommandExecuter()
+ _, out, _ = ce.RunCommandWOutput('which cros_sdk')
+ cros_sdk_binary = out.split()[0]
+ return os.execv(cros_sdk_binary, ['', '--enter'])
+
+
+def CreateMountPointsFromString(mount_strings, chroot_dir):
+ # String has options in the form dir:mount:options
+ mount_points = []
+ if not mount_strings:
+ return mount_points
+ mount_list = mount_strings.split()
+ for mount_string in mount_list:
+ mount_values = mount_string.split(':')
+ external_dir = mount_values[0]
+ mount_dir = mount_values[1]
+ if len(mount_values) > 2:
+ options = mount_values[2]
+ else:
+ options = None
+ mount_point = MountPoint(external_dir, chroot_dir + '/' + mount_dir,
+ getpass.getuser(), options)
+ mount_points.append(mount_point)
+ return mount_points
+
+
+def CreateSymlink(target, link_name):
+ logger.GetLogger().LogFatalIf(
+ target.startswith('/'), "Can't create symlink to absolute path!")
+ real_from_file = misc.GetRoot(link_name)[0] + '/' + target
+ if os.path.realpath(real_from_file) != os.path.realpath(link_name):
+ if os.path.exists(link_name):
+ command = 'rm -rf ' + link_name
+ command_executer.GetCommandExecuter().RunCommand(command)
+ os.symlink(target, link_name)
+
+
+if __name__ == '__main__':
+ retval = Main(sys.argv)
+ sys.exit(retval)