Refactor make_chroot.sh to use enter_chroot, and cleanup complaints.

Now that make_chroot.sh lives alongside enter_chroot, we're able
to invoke it directly and use internal options not exposed through
cros_sdk.  Thus enter_chroot grows a --early_make_chroot flag.

This flag bypasses the normal sudo usage, and runs the command
as root.  It is needed and used by make_chroot for when sudo
may not yet exist (--bootstrap via stage3 lacks sudo).

For where sudo exists and we need access to the source tree,
distfiles, or profile sourcing, enter_chroot is directly used.

For all other invocations we use a single sudo chroot call to
bypass the overhead of enter_chroot.

This is a complete fix to chromium-os:25697 while addressing
all refactoring requests that came up in I8a6c5a26.

Finally, convert all comments into complete sentences, upper
case the leading word, etc to keep reviewers happy.

BUG=chromium-os:25697
TEST=Within a trybot, cros_sdk --bootstrap --replace
TEST=cros_sdk --replace
TEST=cros_sdk --delete
TEST=cros_sdk
Change-Id: I270ee7fc325ef0bea74c61505d25cdbb49a9a333
Reviewed-on: https://gerrit.chromium.org/gerrit/15322
Commit-Ready: Brian Harring <ferringb@chromium.org>
Reviewed-by: Brian Harring <ferringb@chromium.org>
Tested-by: Brian Harring <ferringb@chromium.org>
This commit is contained in:
Brian Harring 2012-02-01 23:50:45 -08:00 committed by Gerrit
parent f539bc3407
commit 357678296a
2 changed files with 174 additions and 170 deletions

View File

@ -31,6 +31,8 @@ DEFINE_boolean official_build $FLAGS_FALSE \
DEFINE_boolean mount $FLAGS_FALSE "Only set up mounts." DEFINE_boolean mount $FLAGS_FALSE "Only set up mounts."
DEFINE_boolean unmount $FLAGS_FALSE "Only tear down mounts." DEFINE_boolean unmount $FLAGS_FALSE "Only tear down mounts."
DEFINE_boolean ssh_agent $FLAGS_TRUE "Import ssh agent." DEFINE_boolean ssh_agent $FLAGS_TRUE "Import ssh agent."
DEFINE_boolean early_make_chroot $FLAGS_FALSE \
"Internal flag. If set, the command is run as root without sudo."
DEFINE_boolean verbose $FLAGS_FALSE "Print out actions taken" DEFINE_boolean verbose $FLAGS_FALSE "Print out actions taken"
# More useful help # More useful help
@ -502,33 +504,47 @@ fi
trap teardown_env EXIT trap teardown_env EXIT
setup_env setup_env
CHROOT_PASSTHRU="BUILDBOT_BUILD=$FLAGS_build_number \ CHROOT_PASSTHRU=(
CHROMEOS_OFFICIAL=$CHROMEOS_OFFICIAL" "BUILDBOT_BUILD=$FLAGS_build_number"
CHROOT_PASSTHRU="${CHROOT_PASSTHRU} \ "CHROMEOS_OFFICIAL=$CHROMEOS_OFFICIAL"
CHROMEOS_RELEASE_APPID=${CHROMEOS_RELEASE_APPID:-"{DEV-BUILD}"}" "CHROMEOS_RELEASE_APPID=${CHROMEOS_RELEASE_APPID:-{DEV-BUILD}}"
# Set CHROMEOS_VERSION_TRACK, CHROMEOS_VERSION_AUSERVER, # Set CHROMEOS_VERSION_TRACK, CHROMEOS_VERSION_AUSERVER,
# CHROMEOS_VERSION_DEVSERVER as environment variables to override the default # CHROMEOS_VERSION_DEVSERVER as environment variables to override the default
# assumptions (local AU server). These are used in cros_set_lsb_release, and # assumptions (local AU server). These are used in cros_set_lsb_release, and
# are used by external Chromium OS builders. # are used by external Chromium OS builders.
CHROOT_PASSTHRU="${CHROOT_PASSTHRU} \
CHROMEOS_VERSION_TRACK=${CHROMEOS_VERSION_TRACK} \ "CHROMEOS_VERSION_TRACK=${CHROMEOS_VERSION_TRACK}"
CHROMEOS_VERSION_AUSERVER=${CHROMEOS_VERSION_AUSERVER} \ "CHROMEOS_VERSION_AUSERVER=${CHROMEOS_VERSION_AUSERVER}"
CHROMEOS_VERSION_DEVSERVER=${CHROMEOS_VERSION_DEVSERVER}" "CHROMEOS_VERSION_DEVSERVER=${CHROMEOS_VERSION_DEVSERVER}"
"EXTERNAL_TRUNK_PATH=${FLAGS_trunk}"
"SSH_AGENT_PID=${SSH_AGENT_PID}"
"SSH_AUTH_SOCK=${SSH_AUTH_SOCK}"
)
# Pass proxy variables into the environment. # Pass proxy variables into the environment.
for type in http_proxy ftp_proxy all_proxy GIT_PROXY_COMMAND GIT_SSH; do for type in http_proxy ftp_proxy all_proxy GIT_PROXY_COMMAND GIT_SSH; do
if [ -n "${!type}" ]; then if [ -n "${!type}" ]; then
CHROOT_PASSTHRU="${CHROOT_PASSTHRU} ${type}=${!type}" CHROOT_PASSTHRU+=( "${type}=${!type}" )
fi fi
done done
# Run command or interactive shell. Also include the non-chrooted path to # Run command or interactive shell. Also include the non-chrooted path to
# the source trunk for scripts that may need to print it (e.g. # the source trunk for scripts that may need to print it (e.g.
# build_image.sh). # build_image.sh).
sudo -- chroot "$FLAGS_chroot" sudo -i -u $USER $CHROOT_PASSTHRU \
EXTERNAL_TRUNK_PATH="${FLAGS_trunk}" SSH_AGENT_PID="${SSH_AGENT_PID}" \ if [ $FLAGS_early_make_chroot -eq $FLAGS_TRUE ]; then
SSH_AUTH_SOCK="${SSH_AUTH_SOCK}" "$@" cmd=( /bin/bash -l -c 'env "$@"' -- )
elif [ ! -x "${FLAGS_chroot}/usr/bin/sudo" ]; then
# Complain that sudo is missing.
error "Failing since the chroot lacks sudo."
error "Requested enter_chroot command was: $@"
exit 127
else
cmd=( sudo -i -u "$USER" )
fi
sudo -- chroot "${FLAGS_chroot}" "${cmd[@]}" "${CHROOT_PASSTHRU[@]}" "$@"
# Remove trap and explicitly unmount # Remove trap and explicitly unmount
trap - EXIT trap - EXIT

View File

@ -12,6 +12,8 @@
SCRIPT_ROOT=$(readlink -f $(dirname "$0")/..) SCRIPT_ROOT=$(readlink -f $(dirname "$0")/..)
. "${SCRIPT_ROOT}/common.sh" || exit 1 . "${SCRIPT_ROOT}/common.sh" || exit 1
ENTER_CHROOT=$(readlink -f $(dirname "$0")/enter_chroot.sh)
# Check if the host machine architecture is supported. # Check if the host machine architecture is supported.
ARCHITECTURE="$(uname -m)" ARCHITECTURE="$(uname -m)"
if [[ "$ARCHITECTURE" != "x86_64" ]]; then if [[ "$ARCHITECTURE" != "x86_64" ]]; then
@ -19,10 +21,10 @@ if [[ "$ARCHITECTURE" != "x86_64" ]]; then
exit 1 exit 1
fi fi
# Script must be run outside the chroot # Script must be run outside the chroot.
assert_outside_chroot assert_outside_chroot
# Define command line flags # Define command line flags.
# See http://code.google.com/p/shflags/wiki/Documentation10x # See http://code.google.com/p/shflags/wiki/Documentation10x
DEFINE_string chroot "$DEFAULT_CHROOT_DIR" \ DEFINE_string chroot "$DEFAULT_CHROOT_DIR" \
@ -36,18 +38,14 @@ DEFINE_string stage3_date "2010.03.09" \
"Use the stage3 with the given date." "Use the stage3 with the given date."
DEFINE_string stage3_path "" \ DEFINE_string stage3_path "" \
"Use the stage3 located on this path." "Use the stage3 located on this path."
DEFINE_boolean cros_sdk $FLAGS_FALSE "Internal: we're called from cros_sdk"
# Parse command line flags # Parse command line flags.
FLAGS_HELP="usage: $SCRIPT_NAME [flags]" FLAGS_HELP="usage: $SCRIPT_NAME [flags]"
FLAGS "$@" || exit 1 FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}" eval set -- "${FLAGS_ARGV}"
check_flags_only_and_allow_null_arg "$@" && set -- check_flags_only_and_allow_null_arg "$@" && set --
if [ "${FLAGS_cros_sdk}" == "${FLAGS_TRUE}" ]; then CROS_LOG_PREFIX=cros_sdk
# HACK: If we're being called by cros_sdk, change the messages.
SCRIPT_NAME=cros_sdk
fi
assert_not_root_user assert_not_root_user
# Set the right umask for chroot creation. # Set the right umask for chroot creation.
@ -78,19 +76,29 @@ if [ "$FLAGS_fast" -eq "${FLAGS_TRUE}" ]; then
EMERGE_CMD="${CHROOT_CHROMITE_DIR}/bin/parallel_emerge" EMERGE_CMD="${CHROOT_CHROMITE_DIR}/bin/parallel_emerge"
fi fi
function in_chroot { ENTER_CHROOT_ARGS=(
sudo "${CHROOT_PASSTHRU[@]}" chroot "$FLAGS_chroot" "$@" CROS_WORKON_SRCROOT="$CHROOT_TRUNK"
PORTAGE_USERNAME="$USER"
IGNORE_PREFLIGHT_BINHOST="$IGNORE_PREFLIGHT_BINHOST"
)
# Invoke enter_chroot. This can only be used after sudo has been installed.
function enter_chroot {
"$ENTER_CHROOT" --chroot "$FLAGS_chroot" -- "${ENTER_CHROOT_ARGS[@]}" "$@"
} }
function bash_chroot { # Invoke enter_chroot running the command as root, and w/out sudo.
# Use $* not $@ since 'bash -c' needs a single arg # This should be used prior to sudo being merged.
# Use -l to force source of /etc/profile (login shell) function early_enter_chroot() {
sudo "${CHROOT_PASSTHRU[@]}" chroot "$FLAGS_chroot" bash -l -c "$*" "$ENTER_CHROOT" --chroot "$FLAGS_chroot" --early_make_chroot \
-- "${ENTER_CHROOT_ARGS[@]}" "$@"
} }
function sudo_chroot { # Run a command within the chroot. The main usage of this is to avoid
# The same as bash_chroot, except ran as the normal user. # the overhead of enter_chroot, and do not need access to the source tree,
sudo chroot "$FLAGS_chroot" sudo -i -u ${USER} "${CHROOT_PASSTHRU[@]}" -- "$@" # don't need the actual chroot profile env, and can run the command as root.
sudo_chroot() {
sudo chroot "${FLAGS_chroot}" "$@"
} }
function cleanup { function cleanup {
@ -99,56 +107,55 @@ function cleanup {
} }
function delete_existing { function delete_existing {
# Delete old chroot dir # Delete old chroot dir.
if [[ -e "$FLAGS_chroot" ]]; then if [[ ! -e "$FLAGS_chroot" ]]; then
echo "$SCRIPT_NAME: Cleaning up old mount points..." return
cleanup
echo "$SCRIPT_NAME: Deleting $FLAGS_chroot..."
sudo rm -rf "$FLAGS_chroot"
echo "$SCRIPT_NAME: Done."
fi fi
info "Cleaning up old mount points..."
cleanup
info "Deleting $FLAGS_chroot..."
sudo rm -rf "$FLAGS_chroot"
info "Done."
} }
function init_users () { function init_users () {
echo "$SCRIPT_NAME: Set timezone..." info "Set timezone..."
# date +%Z has trouble with daylight time, so use host's info # date +%Z has trouble with daylight time, so use host's info.
in_chroot rm -f /etc/localtime sudo rm -f "${FLAGS_chroot}/etc/localtime"
if [ -f /etc/localtime ] ; then if [ -f /etc/localtime ] ; then
sudo cp /etc/localtime "${FLAGS_chroot}/etc" sudo cp /etc/localtime "${FLAGS_chroot}/etc"
else else
in_chroot ln -sf /usr/share/zoneinfo/PST8PDT /etc/localtime sudo ln -sf /usr/share/zoneinfo/PST8PDT "${FLAGS_chroot}/etc/localtime"
fi fi
echo "$SCRIPT_NAME: Adding user/group..." info "Adding user/group..."
# Add ourselves as a user inside the chroot. # Add ourselves as a user inside the chroot.
in_chroot groupadd -g 5000 eng sudo_chroot groupadd -g 5000 eng
# We need the UID to match the host user's. This can conflict with # We need the UID to match the host user's. This can conflict with
# a particular chroot UID. At the same time, the added user has to # a particular chroot UID. At the same time, the added user has to
# be a primary user for the given UID for sudo to work, which is # be a primary user for the given UID for sudo to work, which is
# determined by the order in /etc/passwd. Let's put ourselves on top # determined by the order in /etc/passwd. Let's put ourselves on top
# of the file. # of the file.
in_chroot useradd -o -G ${DEFGROUPS} -g eng -u `id -u` -s \ sudo_chroot useradd -o -G ${DEFGROUPS} -g eng -u `id -u` -s \
/bin/bash -m -c "${FULLNAME}" -p ${CRYPTED_PASSWD} ${USER} /bin/bash -m -c "${FULLNAME}" -p ${CRYPTED_PASSWD} ${USER}
# Because passwd generally isn't sorted and the entry ended up at the # Because passwd generally isn't sorted and the entry ended up at the
# bottom, it is safe to just take it and move it to top instead. # bottom, it is safe to just take it and move it to top instead.
in_chroot sed -e '1{h;d};$!{H;d};$G' -i /etc/passwd sudo sed -e '1{h;d};$!{H;d};$G' -i "${FLAGS_chroot}/etc/passwd"
} }
function init_setup () { function init_setup () {
echo "$SCRIPT_NAME: Running init_setup()..." info "Running init_setup()..."
sudo mkdir -p "${FLAGS_chroot}/usr" sudo mkdir -p -m 755 "${FLAGS_chroot}/usr" \
"${FLAGS_chroot}/usr/local/portage" \
"${FLAGS_chroot}"/"${CROSSDEV_OVERLAY}"
sudo ln -sf "${CHROOT_TRUNK}/src/third_party/portage" \ sudo ln -sf "${CHROOT_TRUNK}/src/third_party/portage" \
"${FLAGS_chroot}/usr/portage" "${FLAGS_chroot}/usr/portage"
sudo mkdir -p "${FLAGS_chroot}/usr/local/portage"
sudo chmod 755 "${FLAGS_chroot}/usr/local/portage"
sudo ln -sf "${CHROOT_TRUNK}/src/third_party/chromiumos-overlay" \ sudo ln -sf "${CHROOT_TRUNK}/src/third_party/chromiumos-overlay" \
"${FLAGS_chroot}"/"${CHROOT_OVERLAY}" "${FLAGS_chroot}"/"${CHROOT_OVERLAY}"
sudo ln -sf "${CHROOT_TRUNK}/src/third_party/portage-stable" \ sudo ln -sf "${CHROOT_TRUNK}/src/third_party/portage-stable" \
"${FLAGS_chroot}"/"${PORTAGE_STABLE_OVERLAY}" "${FLAGS_chroot}"/"${PORTAGE_STABLE_OVERLAY}"
sudo mkdir -p "${FLAGS_chroot}"/"${CROSSDEV_OVERLAY}"
sudo chmod 755 "${FLAGS_chroot}"/"${CROSSDEV_OVERLAY}"
# Some operations need an mtab # Some operations need an mtab.
in_chroot ln -s /proc/mounts /etc/mtab sudo ln -s /proc/mounts "${FLAGS_chroot}/etc/mtab"
# Set up sudoers. Inside the chroot, the user can sudo without a password. # Set up sudoers. Inside the chroot, the user can sudo without a password.
# (Safe enough, since the only way into the chroot is to 'sudo chroot', so # (Safe enough, since the only way into the chroot is to 'sudo chroot', so
@ -166,20 +173,19 @@ Defaults env_keep += all_proxy
root ALL=(ALL) ALL root ALL=(ALL) ALL
$USER ALL=NOPASSWD: ALL $USER ALL=NOPASSWD: ALL
EOF EOF
bash_chroot "find /etc/sudoers* -type f -exec chmod 0440 {} +" sudo find "${FLAGS_chroot}/etc/"sudoers* -type f -exec chmod 0440 {} +
bash_chroot "chown -R root:root /etc/sudoers*" # Fix bad group for some. # Fix bad group for some.
sudo chown -R root:root "${FLAGS_chroot}/etc/"sudoers*
echo "$SCRIPT_NAME: Setting up hosts/resolv..." info "Setting up hosts/resolv..."
# Copy config from outside chroot into chroot # Copy config from outside chroot into chroot.
sudo cp /etc/hosts "$FLAGS_chroot/etc/hosts" sudo cp /etc/{hosts,resolv.conf} "$FLAGS_chroot/etc/"
sudo chmod 0644 "$FLAGS_chroot/etc/hosts" sudo chmod 0644 "$FLAGS_chroot"/etc/{hosts,resolv.conf}
sudo cp /etc/resolv.conf "$FLAGS_chroot/etc/resolv.conf"
sudo chmod 0644 "$FLAGS_chroot/etc/resolv.conf"
# Setup host make.conf. This includes any overlay that we may be using # Setup host make.conf. This includes any overlay that we may be using
# and a pointer to pre-built packages. # and a pointer to pre-built packages.
# TODO: This should really be part of a profile in the portage # TODO: This should really be part of a profile in the portage.
echo "$SCRIPT_NAME: Setting up /etc/make.*..." info "Setting up /etc/make.*..."
sudo mv "${FLAGS_chroot}"/etc/make.conf{,.orig} sudo mv "${FLAGS_chroot}"/etc/make.conf{,.orig}
sudo ln -sf "${CHROOT_CONFIG}/make.conf.amd64-host" \ sudo ln -sf "${CHROOT_CONFIG}/make.conf.amd64-host" \
"${FLAGS_chroot}/etc/make.conf" "${FLAGS_chroot}/etc/make.conf"
@ -187,14 +193,14 @@ EOF
sudo ln -sf "${CHROOT_OVERLAY}/profiles/default/linux/amd64/10.0" \ sudo ln -sf "${CHROOT_OVERLAY}/profiles/default/linux/amd64/10.0" \
"${FLAGS_chroot}/etc/make.profile" "${FLAGS_chroot}/etc/make.profile"
# Create make.conf.user # Create make.conf.user .
sudo touch "${FLAGS_chroot}"/etc/make.conf.user sudo touch "${FLAGS_chroot}"/etc/make.conf.user
sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.user sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.user
# Create directories referred to by our conf files. # Create directories referred to by our conf files.
sudo mkdir -p -m 775 "${FLAGS_chroot}/var/lib/portage/distfiles" sudo mkdir -p -m 775 "${FLAGS_chroot}/var/lib/portage/distfiles" \
sudo mkdir -p -m 775 "${FLAGS_chroot}/var/lib/portage/distfiles-target" "${FLAGS_chroot}/var/lib/portage/distfiles-target" \
sudo mkdir -p -m 775 "${FLAGS_chroot}/var/lib/portage/pkgs" "${FLAGS_chroot}/var/lib/portage/pkgs"
if [[ $FLAGS_jobs -ne -1 ]]; then if [[ $FLAGS_jobs -ne -1 ]]; then
EMERGE_JOBS="--jobs=$FLAGS_jobs" EMERGE_JOBS="--jobs=$FLAGS_jobs"
@ -212,19 +218,22 @@ EOF
# TODO(zbehan): Configure stuff that is usually configured in postinst's, # TODO(zbehan): Configure stuff that is usually configured in postinst's,
# but wasn't. Fix the postinst's. crosbug.com/18036 # but wasn't. Fix the postinst's. crosbug.com/18036
echo "Running post-inst configuration hacks" info "Running post-inst configuration hacks"
in_chroot env-update early_enter_chroot env-update
if [ -f ${FLAGS_chroot}/usr/bin/build-docbook-catalog ]; then if [ -f ${FLAGS_chroot}/usr/bin/build-docbook-catalog ]; then
# For too ancient chroots that didn't have build-docbook-catalog, this # For too ancient chroots that didn't have build-docbook-catalog, this
# is not relevant, and will get installed during update. # is not relevant, and will get installed during update.
in_chroot build-docbook-catalog early_enter_chroot build-docbook-catalog
# Configure basic stuff needed.
early_enter_chroot env-update
fi fi
# Configure basic stuff needed # This is basically a sanity check of our chroot. If any of these
in_chroot env-update # don't exist, then either bind mounts have failed, an invocation
bash_chroot ls -l /etc/make.conf # from above is broke, or some assumption about the stage3 is no longer
bash_chroot ls -l /etc/make.profile # true.
bash_chroot ls -l /usr/local/portage/chromiumos/profiles/default/linux/amd64/10.0 early_enter_chroot ls -l /etc/make.{conf,profile} \
/usr/local/portage/chromiumos/profiles/default/linux/amd64/10.0
target="${FLAGS_chroot}/etc/profile.d" target="${FLAGS_chroot}/etc/profile.d"
sudo mkdir -p "${target}" sudo mkdir -p "${target}"
@ -257,15 +266,15 @@ EOF
"${FLAGS_chroot}/home/$USER/.local/lib/python2.6/site-packages/" "${FLAGS_chroot}/home/$USER/.local/lib/python2.6/site-packages/"
chmod a+x "$FLAGS_chroot/home/$USER/.bashrc" chmod a+x "$FLAGS_chroot/home/$USER/.bashrc"
# Automatically change to scripts directory # Automatically change to scripts directory.
echo 'cd ${CHROOT_CWD:-~/trunk/src/scripts}' \ echo 'cd ${CHROOT_CWD:-~/trunk/src/scripts}' \
>> "$FLAGS_chroot/home/$USER/.bash_profile" >> "$FLAGS_chroot/home/$USER/.bash_profile"
# Enable bash completion for build scripts # Enable bash completion for build scripts.
echo ". ~/trunk/src/scripts/bash_completion" \ echo ". ~/trunk/src/scripts/bash_completion" \
>> "$FLAGS_chroot/home/$USER/.bashrc" >> "$FLAGS_chroot/home/$USER/.bashrc"
# Warn if attempting to use source control commands inside the chroot # Warn if attempting to use source control commands inside the chroot.
for NOUSE in svn gcl gclient for NOUSE in svn gcl gclient
do do
echo "alias $NOUSE='echo In the chroot, it is a bad idea to run $NOUSE'" \ echo "alias $NOUSE='echo In the chroot, it is a bad idea to run $NOUSE'" \
@ -278,16 +287,16 @@ EOF
fi fi
if [[ -f $HOME/.gitconfig ]]; then if [[ -f $HOME/.gitconfig ]]; then
# Copy .gitconfig into chroot so repo and git can be used from inside # Copy .gitconfig into chroot so repo and git can be used from inside.
# This is required for repo to work since it validates the email address # This is required for repo to work since it validates the email address.
echo "Copying ~/.gitconfig into chroot" echo "Copying ~/.gitconfig into chroot"
cp $HOME/.gitconfig "$FLAGS_chroot/home/$USER/" cp $HOME/.gitconfig "$FLAGS_chroot/home/$USER/"
fi fi
} }
# Handle deleting an existing environment # Handle deleting an existing environment.
if [[ $FLAGS_delete -eq $FLAGS_TRUE || \ if [[ $FLAGS_delete -eq $FLAGS_TRUE || \
$FLAGS_replace -eq $FLAGS_TRUE ]]; then $FLAGS_replace -eq $FLAGS_TRUE ]]; then
delete_existing delete_existing
[[ $FLAGS_delete -eq $FLAGS_TRUE ]] && exit 0 [[ $FLAGS_delete -eq $FLAGS_TRUE ]] && exit 0
fi fi
@ -301,8 +310,6 @@ PORTAGE_STABLE_OVERLAY="/usr/local/portage/stable"
CROSSDEV_OVERLAY="/usr/local/portage/crossdev" CROSSDEV_OVERLAY="/usr/local/portage/crossdev"
CHROOT_OVERLAY="/usr/local/portage/chromiumos" CHROOT_OVERLAY="/usr/local/portage/chromiumos"
CHROOT_STATE="${FLAGS_chroot}/etc/debian_chroot" CHROOT_STATE="${FLAGS_chroot}/etc/debian_chroot"
CHROOT_PASSTHRU=(CROS_WORKON_SRCROOT="$CHROOT_TRUNK" PORTAGE_USERNAME="$USER"
IGNORE_PREFLIGHT_BINHOST="$IGNORE_PREFLIGHT_BINHOST")
# Pass proxy variables into the environment. # Pass proxy variables into the environment.
for type in http ftp all; do for type in http ftp all; do
@ -312,81 +319,68 @@ for type in http ftp all; do
fi fi
done done
# Create the base Gentoo stage3 based on last version put in chroot # Create the base Gentoo stage3 based on last version put in chroot.
STAGE3="${OVERLAY}/chromeos/stage3/stage3-amd64-${FLAGS_stage3_date}.tar.bz2" STAGE3="${OVERLAY}/chromeos/stage3/stage3-amd64-${FLAGS_stage3_date}.tar.bz2"
if [ -f $CHROOT_STATE ] && \ if [ -f $CHROOT_STATE ] && \
! sudo egrep -q "^STAGE3=$STAGE3" $CHROOT_STATE >/dev/null 2>&1 ! sudo egrep -q "^STAGE3=$STAGE3" $CHROOT_STATE >/dev/null 2>&1
then then
echo "$SCRIPT_NAME: STAGE3 version has changed." info "STAGE3 version has changed."
delete_existing delete_existing
fi fi
if [ -n "${FLAGS_stage3_path}" ]; then if [ -n "${FLAGS_stage3_path}" ]; then
if [ -f "${FLAGS_stage3_path}" ]; then if [ ! -f "${FLAGS_stage3_path}" ]; then
STAGE3="${FLAGS_stage3_path}"
else
error "Invalid stage3!" error "Invalid stage3!"
exit 1; exit 1;
fi fi
STAGE3="${FLAGS_stage3_path}"
fi fi
# Create the destination directory # Create the destination directory.
mkdir -p "$FLAGS_chroot" mkdir -p "$FLAGS_chroot"
echo echo
if [ -f $CHROOT_STATE ] if [ -f $CHROOT_STATE ]
then then
echo "$SCRIPT_NAME: STAGE3 already set up. Skipping..." info "STAGE3 already set up. Skipping..."
else else
echo "$SCRIPT_NAME: Unpacking STAGE3..." info "Unpacking STAGE3..."
sudo tar -xp -I $(type -p pbzip2 || echo bzip2) \ sudo tar -xp -I $(type -p pbzip2 || echo bzip2) \
-C "${FLAGS_chroot}" -f "${STAGE3}" -C "${FLAGS_chroot}" -f "${STAGE3}"
sudo rm -f $FLAGS_chroot/etc/make.globals sudo rm -f "$FLAGS_chroot/etc/"make.{globals,conf.user}
sudo rm -f $FLAGS_chroot/etc/make.conf.user
fi fi
# Set up users, if needed, before mkdir/mounts below # Set up users, if needed, before mkdir/mounts below.
[ -f $CHROOT_STATE ] || init_users [ -f $CHROOT_STATE ] || init_users
echo echo
echo "$SCRIPT_NAME: Setting up mounts..." info "Setting up mounts..."
# Set up necessary mounts and make sure we clean them up on exit # Set up necessary mounts and make sure we clean them up on exit.
trap cleanup EXIT sudo mkdir -p "${FLAGS_chroot}/${CHROOT_TRUNK}" "${FLAGS_chroot}/run"
sudo mkdir -p "${FLAGS_chroot}/${CHROOT_TRUNK}"
sudo mount --bind /dev "${FLAGS_chroot}/dev"
sudo mount --bind "${GCLIENT_ROOT}" "${FLAGS_chroot}/${CHROOT_TRUNK}"
sudo mount none -t proc "$FLAGS_chroot/proc"
sudo mount none -t devpts "$FLAGS_chroot/dev/pts"
sudo mkdir -p "${FLAGS_chroot}/run"
if [ -d /run ]; then
sudo mount --bind /run "$FLAGS_chroot/run"
if [ -d /run/shm ]; then
sudo mount --bind /run/shm "$FLAGS_chroot/run/shm"
fi
fi
PREBUILT_SETUP="$FLAGS_chroot/etc/make.conf.prebuilt_setup" PREBUILT_SETUP="$FLAGS_chroot/etc/make.conf.prebuilt_setup"
if [[ -z "$IGNORE_PREFLIGHT_BINHOST" ]]; then if [[ -z "$IGNORE_PREFLIGHT_BINHOST" ]]; then
echo 'PORTAGE_BINHOST="$FULL_BINHOST"' | sudo_clobber "$PREBUILT_SETUP" echo 'PORTAGE_BINHOST="$FULL_BINHOST"'
else fi | sudo_clobber "$PREBUILT_SETUP"
sudo_clobber "$PREBUILT_SETUP" < /dev/null
fi
sudo chmod 0644 "$PREBUILT_SETUP" sudo chmod 0644 "$PREBUILT_SETUP"
# For bootstrapping from old wget, disable certificate checking. Once we've # For bootstrapping from old wget, disable certificate checking. Once we've
# upgraded to new curl (below), certificate checking is re-enabled. See # upgraded to new curl (below), certificate checking is re-enabled. See
# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=409938 # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=409938
bash_chroot 'cat > /etc/make.conf.fetchcommand_setup' <<'EOF' sudo_clobber "${FLAGS_chroot}/etc/make.conf.fetchcommand_setup" <<'EOF'
FETCHCOMMAND="/usr/bin/wget -t 5 -T 60 --no-check-certificate --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\${URI}\"" FETCHCOMMAND="/usr/bin/wget -t 5 -T 60 --no-check-certificate --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
RESUMECOMMAND="/usr/bin/wget -c -t 5 -T 60 --no-check-certificate --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\${URI}\"" RESUMECOMMAND="/usr/bin/wget -c -t 5 -T 60 --no-check-certificate --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
EOF EOF
sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.fetchcommand_setup
bash_chroot 'cat > /etc/make.conf.host_setup' <<EOF sudo_clobber "${FLAGS_chroot}/etc/make.conf.host_setup" <<EOF
# Created by make_chroot # Created by make_chroot.
source make.conf.prebuilt_setup source make.conf.prebuilt_setup
source make.conf.fetchcommand_setup source make.conf.fetchcommand_setup
MAKEOPTS="-j${NUM_JOBS}" MAKEOPTS="-j${NUM_JOBS}"
EOF EOF
sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.host_setup
sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.host_setup \
"${FLAGS_chroot}"/etc/make.conf.fetchcommand_setup
if ! [ -f "$CHROOT_STATE" ];then if ! [ -f "$CHROOT_STATE" ];then
INITIALIZE_CHROOT=1 INITIALIZE_CHROOT=1
@ -394,42 +388,43 @@ fi
if [ -z "${INITIALIZE_CHROOT}" ];then if [ -z "${INITIALIZE_CHROOT}" ];then
echo "$SCRIPT_NAME: chroot already initialized. Skipping..." info "chroot already initialized. Skipping..."
else else
# run all the init stuff to setup the env # Run all the init stuff to setup the env.
init_setup init_setup
fi fi
# Add file to indicate that it is a chroot # Add file to indicate that it is a chroot.
# Add version of $STAGE3 for update checks # Add version of $STAGE3 for update checks.
sudo sh -c "echo STAGE3=$STAGE3 > $CHROOT_STATE" sudo sh -c "echo STAGE3=$STAGE3 > $CHROOT_STATE"
echo "$SCRIPT_NAME: Updating portage" info "Updating portage"
in_chroot emerge -uNv portage early_enter_chroot emerge -uNv portage
echo "$SCRIPT_NAME: Updating toolchain" info "Updating toolchain"
in_chroot emerge -uNv $USEPKG '>=sys-devel/gcc-4.4' sys-libs/glibc \ early_enter_chroot emerge -uNv $USEPKG '>=sys-devel/gcc-4.4' sys-libs/glibc \
sys-devel/binutils sys-kernel/linux-headers sys-devel/binutils sys-kernel/linux-headers
# HACK: Select the latest toolchain. We're assuming that when this is # HACK: Select the latest toolchain. We're assuming that when this is
# ran, the chroot has no experimental versions of new toolchains, just # ran, the chroot has no experimental versions of new toolchains, just
# one that is very old, and one that was just emerged. # one that is very old, and one that was just emerged.
CHOST="$(in_chroot portageq envvar CHOST)" CHOST="$(early_enter_chroot portageq envvar CHOST)"
LATEST="$(in_chroot gcc-config -l | grep "${CHOST}" | tail -n1 | \ LATEST="$(early_enter_chroot gcc-config -l | grep "${CHOST}" | tail -n1 | \
cut -f3 -d' ')" cut -f3 -d' ')"
in_chroot gcc-config "${LATEST}" early_enter_chroot gcc-config "${LATEST}"
in_chroot emerge --unmerge "<sys-devel/gcc-${LATEST/${CHOST}-/}" early_enter_chroot emerge --unmerge "<sys-devel/gcc-${LATEST/${CHOST}-/}"
# dhcpcd is included in 'world' by the stage3 that we pull in for some reason. # dhcpcd is included in 'world' by the stage3 that we pull in for some reason.
# We have no need to install it in our host environment, so pull it out here. # We have no need to install it in our host environment, so pull it out here.
echo "$SCRIPT_NAME: Deselecting dhcpcd" info "Deselecting dhcpcd"
in_chroot $EMERGE_CMD --deselect dhcpcd early_enter_chroot $EMERGE_CMD --deselect dhcpcd
echo "$SCRIPT_NAME: Running emerge ccache curl sudo ..." info "Running emerge ccache curl sudo ..."
in_chroot $EMERGE_CMD -uNv $USEPKG ccache net-misc/curl sudo $EMERGE_JOBS early_enter_chroot $EMERGE_CMD -uNv $USEPKG $EMERGE_JOS \
ccache net-misc/curl sudo
# Curl is now installed, so we can depend on it now. # Curl is now installed, so we can depend on it now.
bash_chroot 'cat > /etc/make.conf.fetchcommand_setup' <<'EOF' sudo_clobber "${FLAGS_chroot}/etc/make.conf.fetchcommand_setup" <<'EOF'
FETCHCOMMAND='curl -f -y 30 --retry 9 -L --output \${DISTDIR}/\${FILE} \${URI}' FETCHCOMMAND='curl -f -y 30 --retry 9 -L --output \${DISTDIR}/\${FILE} \${URI}'
RESUMECOMMAND='curl -f -y 30 -C - --retry 9 -L --output \${DISTDIR}/\${FILE} \${URI}' RESUMECOMMAND='curl -f -y 30 -C - --retry 9 -L --output \${DISTDIR}/\${FILE} \${URI}'
EOF EOF
@ -438,44 +433,37 @@ sudo chmod 0644 "${FLAGS_chroot}"/etc/make.conf.fetchcommand_setup
if [ -n "${INITIALIZE_CHROOT}" ]; then if [ -n "${INITIALIZE_CHROOT}" ]; then
# If we're creating a new chroot, we also want to set it to the latest # If we're creating a new chroot, we also want to set it to the latest
# version. # version.
sudo_chroot \ enter_chroot \
"${CHROOT_TRUNK}/src/scripts/run_chroot_version_hooks" --force_latest "${CHROOT_TRUNK}/src/scripts/run_chroot_version_hooks" --force_latest
fi fi
# Update chroot # Update chroot.
UPDATE_ARGS="" UPDATE_ARGS=()
if [[ $FLAGS_usepkg -eq $FLAGS_TRUE ]]; then if [[ $FLAGS_usepkg -eq $FLAGS_TRUE ]]; then
UPDATE_ARGS+=" --usepkg" UPDATE_ARGS+=( --usepkg )
else else
UPDATE_ARGS+=" --nousepkg" UPDATE_ARGS+=( --nousepkg )
fi fi
if [[ ${FLAGS_fast} -eq ${FLAGS_TRUE} ]]; then if [[ ${FLAGS_fast} -eq ${FLAGS_TRUE} ]]; then
UPDATE_ARGS+=" --fast" UPDATE_ARGS+=( --fast )
else else
UPDATE_ARGS+=" --nofast" UPDATE_ARGS+=( --nofast )
fi fi
sudo_chroot "${CHROOT_TRUNK}/src/scripts/update_chroot" ${UPDATE_ARGS} enter_chroot "${CHROOT_TRUNK}/src/scripts/update_chroot" "${UPDATE_ARGS[@]}"
# Unmount trunk CHROOT_EXAMPLE_OPT=""
sudo umount "${FLAGS_chroot}/${CHROOT_TRUNK}" if [[ "$FLAGS_chroot" != "$DEFAULT_CHROOT_DIR" ]]; then
# Clean up the chroot mounts
trap - EXIT
cleanup
if [[ "$FLAGS_chroot" = "$DEFAULT_CHROOT_DIR" ]]; then
CHROOT_EXAMPLE_OPT=""
else
CHROOT_EXAMPLE_OPT="--chroot=$FLAGS_chroot" CHROOT_EXAMPLE_OPT="--chroot=$FLAGS_chroot"
fi fi
print_time_elapsed print_time_elapsed
echo cat <<EOF
echo "$SCRIPT_NAME: All set up. To enter the chroot, run:" ${CROS_LOG_PREFIX:-cros_sdk}: All set up. To enter the chroot, run:"
echo "$SCRIPT_NAME: $ cros_sdk --enter $CHROOT_EXAMPLE_OPT" ${CROS_LOG_PREFIX:-cros_sdk}: $ cros_sdk --enter $CHROOT_EXAMPLE_OPT"
echo ""
echo "CAUTION: Do *NOT* rm -rf the chroot directory; if there are stale bind" CAUTION: Do *NOT* rm -rf the chroot directory; if there are stale bind
echo "mounts you may end up deleting your source tree too. To unmount and" mounts you may end up deleting your source tree too. To unmount and
echo "delete the chroot cleanly, use:" delete the chroot cleanly, use:
echo "$ $SCRIPT_NAME --delete $CHROOT_EXAMPLE_OPT" $ cros_sdk --delete $CHROOT_EXAMPLE_OPT
EOF