#!/bin/bash -e # Copyright (c) 2010 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # This script installs Debian-derived distributions in a chroot environment. # It can for example be used to have an accurate 32bit build and test # environment when otherwise working on a 64bit machine. # N. B. it is unlikely that this script will ever work on anything other than a # Debian-derived system. # Check that we are running as a regular user [ "$(id -nu)" = root ] && { echo "Run this script as a regular user and provide your \"sudo\"" \ "password if requested" >&2 exit 1 } mkdir -p "$HOME/chroot/" # Error handler trap 'exit 1' INT TERM QUIT trap 'sudo apt-get clean; tput bel; echo; echo Failed' EXIT # Install any missing applications that this script relies on. If these packages # are already installed, don't force another "apt-get install". That would # prevent them from being auto-removed, if they ever become eligible for that. # And as this script only needs the packages once, there is no good reason to # introduce a hard dependency on things such as dchroot and debootstrap. dep= for i in dchroot debootstrap; do [ -d /usr/share/doc/"$i" ] || dep="$dep $i" done [ -n "$dep" ] && sudo apt-get -y install $dep sudo apt-get -y install schroot # Create directory for chroot sudo mkdir -p /var/lib/chroot # Find chroot environments that can be installed with debootstrap targets="$(cd /usr/share/debootstrap/scripts ls | grep '^[a-z]*$')" # Ask user to pick one of the available targets echo "The following targets are available to be installed in a chroot:" j=1; for i in $targets; do printf '%4d: %s\n' "$j" "$i" j=$(($j+1)) done while :; do printf "Which target would you like to install: " read n [ "$n" -gt 0 -a "$n" -lt "$j" ] >&/dev/null && break done j=1; for i in $targets; do [ "$j" -eq "$n" ] && { distname="$i"; break; } j=$(($j+1)) done # On x86-64, ask whether the user wants to install x86-32 or x86-64 archflag= arch= if [ "$(uname -m)" = x86_64 ]; then while :; do echo "You are running a 64bit kernel. This allows you to install either a" printf "32bit or a 64bit chroot environment. %s" \ "Which one do you want (32, 64) " read arch [ "${arch}" == 32 -o "${arch}" == 64 ] && break done [ "${arch}" == 32 ] && archflag="--arch i386" || archflag="--arch amd64" arch="${arch}bit" fi target="${distname}${arch}" # Don't overwrite an existing installation [ -d /var/lib/chroot/"${target}" ] && { echo "This chroot already exists on your machine." >&2 echo "Delete /var/lib/chroot/${target} if you want to start over." >&2 exit 1 } sudo mkdir -p /var/lib/chroot/"${target}" # Remove stale entry from /etc/schroot/schroot.conf. Entries start # with the target name in square brackets, followed by an arbitrary # number of lines. The entry stops when either the end of file has # been reached, or when the beginning of a new target is encountered. # This means, we cannot easily match for a range of lines in # "sed". Instead, we actually have to iterate over each line and check # whether it is the beginning of a new entry. sudo sed -ni '/^[[]'"${target%bit}"']$/,${:1;n;/^[[]/b2;b1;:2;p;n;b2};p' \ /etc/schroot/schroot.conf # Download base system. This takes some time grep ubuntu.com /usr/share/debootstrap/scripts/"${distname}" >&/dev/null && mirror="http://archive.ubuntu.com/ubuntu" || mirror="http://ftp.us.debian.org/debian" sudo debootstrap ${archflag} "${distname}" /var/lib/chroot/"${target}" \ "$mirror" # Add new entry to /etc/schroot/schroot.conf grep ubuntu.com /usr/share/debootstrap/scripts/"${distname}" >&/dev/null && brand="Ubuntu" || brand="Debian" sudo sh -c 'cat >>/etc/schroot/schroot.conf' </etc/schroot/script-'"${target}" sudo cp /etc/schroot/mount-defaults /etc/schroot/mount-"${target}" echo "$HOME/chroot/.${target} $HOME/chroot none rw,bind 0 0" | sudo sh -c 'cat >>/etc/schroot/mount-'"${target}" mkdir -p "$HOME/chroot/.${target}" # Install a helper script to launch commands in the chroot sudo sh -c 'cat >/usr/local/bin/'"${target%bit}" </dev/null 2>&1 || echo '"'$(id -nu) ALL=(ALL) ALL'"' >>/etc/sudoers' # Install a few more commonly used packages sudo schroot -c "${target%bit}" -p -- apt-get -y install \ autoconf automake1.9 dpkg-dev g++-multilib gcc-multilib gdb less libtool \ strace # If running a 32bit environment on a 64bit machine, install a few binaries # as 64bit. if [ "${arch}" = 32bit ] && file /bin/bash 2>/dev/null | grep -q x86-64; then sudo schroot -c "${target%bit}" -p -- apt-get -y install \ lib64expat1 lib64ncurses5 lib64readline6 lib64z1 dep= for i in binutils gdb strace; do [ -d /usr/share/doc/"$i" ] || dep="$dep $i" done [ -n "$dep" ] && sudo apt-get -y install $dep sudo cp /usr/bin/gdb /var/lib/chroot/${target}/usr/local/bin/ sudo cp /usr/bin/ld /var/lib/chroot/${target}/usr/local/bin/ for i in libbfd libpython; do lib="$({ ldd /usr/bin/ld; ldd /usr/bin/gdb; } | grep "$i" | awk '{ print $3 }')" if [ -n "$lib" -a -r "$lib" ]; then sudo cp "$lib" /var/lib/chroot/${target}/usr/lib64/ fi done for lib in libssl libcrypt; do sudo cp /usr/lib/$lib* /var/lib/chroot/${target}/usr/lib64/ || : done fi # Clean up package files sudo schroot -c "${target%bit}" -p -- apt-get clean sudo apt-get clean # Let the user know what we did trap '' INT TERM QUIT trap '' EXIT cat <