blob: f3b92bd5a655b24b2f65cd06c52d047d9c750103 [file] [log] [blame]
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""cros chroot: Enter the chroot for the current build environment."""
from __future__ import print_function
import argparse
import os
from chromite.cbuildbot import constants
from chromite.cli import command
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import path_util
from chromite.lib import workspace_lib
@command.CommandDecorator('chroot')
class ChrootCommand(command.CliCommand):
"""Enter the chroot."""
# Override base class property to enable stats upload.
upload_stats = True
def _SpecifyNewChrootLocation(self, chroot_dir):
"""Specify a new location for a workspace's chroot.
Args:
chroot_dir: Directory in which to specify the new chroot.
"""
workspace_path = workspace_lib.WorkspacePath()
if not workspace_path:
cros_build_lib.Die('You must be in a workspace, to move its chroot.')
# TODO(dgarrett): Validate chroot_dir, somehow.
workspace_lib.SetChrootDir(workspace_path, chroot_dir)
def _RunChrootCommand(self, cmd):
"""Run the specified command inside the chroot.
Args:
cmd: A list or tuple of strings to use as a command and its arguments.
If empty, run 'bash'.
Returns:
The commands result code.
"""
# If there is no command, run bash.
if not cmd:
cmd = ['bash']
chroot_args = ['--log-level', self.options.log_level]
extra_env = {}
workspace_path = workspace_lib.WorkspacePath()
if workspace_path is not None:
chroot_args.extend(['--chroot', workspace_lib.ChrootPath(workspace_path),
'--workspace', workspace_path])
resolver = path_util.ChrootPathResolver(workspace_path=workspace_path)
extra_env[commandline.CHROOT_CWD_ENV_VAR] = resolver.ToChroot(os.getcwd())
result = cros_build_lib.RunCommand(cmd, print_cmd=False, error_code_ok=True,
cwd=constants.SOURCE_ROOT,
mute_output=False,
enter_chroot=True, extra_env=extra_env,
chroot_args=chroot_args)
return result.returncode
@classmethod
def AddParser(cls, parser):
"""Adds a parser."""
super(cls, ChrootCommand).AddParser(parser)
parser.add_argument(
'--move', help='Specify new directory for workspace chroot.')
parser.add_argument(
'command', nargs=argparse.REMAINDER,
help='(optional) Command to execute inside the chroot.')
def Run(self):
"""Runs `cros chroot`."""
self.options.Freeze()
# Handle the special case of moving the chroot.
if self.options.move:
if self.options.command:
cros_build_lib.Die(
"You can't move a chroot, and use it at the same time.")
self._SpecifyNewChrootLocation(self.options.move)
return 0
# Handle the standard case.
cmd = self.options.command
# If -- was used to separate out the command from arguments, ignore it.
if cmd and cmd[0] == '--':
cmd = cmd[1:]
return self._RunChrootCommand(cmd)