15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/bin/bash -e
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This script installs Debian-derived distributions in a chroot environment.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# It can for example be used to have an accurate 32bit build and test
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# environment when otherwise working on a 64bit machine.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# N. B. it is unlikely that this script will ever work on anything other than a
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Debian-derived system.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Older Debian based systems had both "admin" and "adm" groups, with "admin"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# apparently being used in more places. Newer distributions have standardized
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch# on just the "adm" group. Check /etc/group for the preferred name of the
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# administrator group.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)admin=$(grep '^admin:' /etc/group >&/dev/null && echo admin || echo adm)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)usage() {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "usage: ${0##*/} [-m mirror] [-g group,...] [-s] [-c]"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-b dir       additional directories that should be bind mounted,"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo '             or "NONE".'
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "             Default: if local filesystems present, ask user for help"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-g group,... groups that can use the chroot unauthenticated"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "             Default: '${admin}' and current user's group ('$(id -gn)')"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-l           List all installed chroot environments"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-m mirror    an alternate repository mirror for package downloads"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-s           configure default deb-srcs"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-c           always copy 64bit helper binaries to 32bit chroot"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "-h           this help message"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)process_opts() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local OPTNAME OPTIND OPTERR OPTARG
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while getopts ":b:g:lm:sch" OPTNAME; do
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case "$OPTNAME" in
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      b)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if [ "${OPTARG}" = "NONE" -a -z "${bind_mounts}" ]; then
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          bind_mounts="${OPTARG}"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if [ "${bind_mounts}" = "NONE" -o "${OPTARG}" = "${OPTARG#/}" -o \
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ! -d "${OPTARG}" ]; then
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            echo "Invalid -b option(s)"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            usage
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            exit 1
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          fi
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          bind_mounts="${bind_mounts}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)${OPTARG} ${OPTARG} none rw,bind 0 0"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fi
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        [ -n "${OPTARG}" ] &&
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chroot_groups="${chroot_groups}${chroot_groups:+,}${OPTARG}"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        list_all_chroots
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exit
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if [ -n "${mirror}" ]; then
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          echo "You can only specify exactly one mirror location"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          usage
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          exit 1
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fi
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mirror="$OPTARG"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      s)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        add_srcs="y"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      c)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        copy_64="y"
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      h)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        usage
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exit 0
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      \:)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        echo "'-$OPTARG' needs an argument."
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        usage
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exit 1
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        echo "invalid command-line option: $OPTARG"
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        usage
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        exit 1
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ;;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    esac
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ $# -ge ${OPTIND} ]; then
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    eval echo "Unexpected command line argument: \${${OPTIND}}"
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    usage
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exit 1
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)list_all_chroots() {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for i in /var/lib/chroot/*; do
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i="${i##*/}"
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ "${i}" = "*" ] && continue
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -x "/usr/local/bin/${i%bit}" ] || continue
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    grep -qs "^\[${i%bit}\]\$" /etc/schroot/schroot.conf || continue
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -r "/etc/schroot/script-${i}" -a \
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -r "/etc/schroot/mount-${i}" ] || continue
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "${i%bit}"
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)getkey() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT HUP
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stty -echo iuclc -icanon 2>/dev/null
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dd count=1 bs=1 2>/dev/null
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  )
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chr() {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf "\\$(printf '%03o' "$1")"
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ord() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf '%d' $(printf '%c' "$1" | od -tu1 -An)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)is_network_drive() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  stat -c %T -f "$1/" 2>/dev/null |
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    egrep -qs '^nfs|cifs|smbfs'
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check that we are running as a regular user
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ "$(id -nu)" = root ] && {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Run this script as a regular user and provide your \"sudo\""           \
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "password if requested" >&2
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 1
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)process_opts "$@"
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "This script will help you through the process of installing a"
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "Debian or Ubuntu distribution in a chroot environment. You will"
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "have to provide your \"sudo\" password when requested."
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Error handler
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)trap 'exit 1' INT TERM QUIT HUP
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)trap 'sudo apt-get clean; tput bel; echo; echo Failed' EXIT
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Install any missing applications that this script relies on. If these packages
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# are already installed, don't force another "apt-get install". That would
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# prevent them from being auto-removed, if they ever become eligible for that.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# And as this script only needs the packages once, there is no good reason to
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# introduce a hard dependency on things such as dchroot and debootstrap.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dep=
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for i in dchroot debootstrap libwww-perl; do
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -d /usr/share/doc/"$i" ] || dep="$dep $i"
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ -n "$dep" ] && sudo apt-get -y install $dep
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo apt-get -y install schroot
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Create directory for chroot
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo mkdir -p /var/lib/chroot
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Find chroot environments that can be installed with debootstrap
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)targets="$(cd /usr/share/debootstrap/scripts
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ls | grep '^[a-z]*$')"
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Ask user to pick one of the available targets
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "The following targets are available to be installed in a chroot:"
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)j=1; for i in $targets; do
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf '%4d: %s\n' "$j" "$i"
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  j=$(($j+1))
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)while :; do
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf "Which target would you like to install: "
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read n
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ "$n" -gt 0 -a "$n" -lt "$j" ] >&/dev/null && break
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)j=1; for i in $targets; do
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ "$j" -eq "$n" ] && { distname="$i"; break; }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  j=$(($j+1))
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# On x86-64, ask whether the user wants to install x86-32 or x86-64
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)archflag=
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)arch=
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "$(uname -m)" = x86_64 ]; then
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while :; do
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "You are running a 64bit kernel. This allows you to install either a"
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf "32bit or a 64bit chroot environment. %s"                           \
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "Which one do you want (32, 64) "
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read arch
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ "${arch}" == 32 -o "${arch}" == 64 ] && break
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ "${arch}" == 32 ] && archflag="--arch i386" || archflag="--arch amd64"
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  arch="${arch}bit"
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)target="${distname}${arch}"
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Don't accidentally overwrite an existing installation
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ -d /var/lib/chroot/"${target}" ] && {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while :; do
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "This chroot already exists on your machine."
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if schroot -l --all-sessions 2>&1 |
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       sed 's/^session://' |
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       grep -qs "^${target%bit}-"; then
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "And it appears to be in active use. Terminate all programs that"
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "are currently using the chroot environment and then re-run this"
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "script."
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "If you still get an error message, you might have stale mounts"
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "that you forgot to delete. You can always clean up mounts by"
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "executing \"${target%bit} -c\"."
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exit 1
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "I can abort installation, I can overwrite the existing chroot,"
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "or I can delete the old one and then exit. What would you like to"
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf "do (a/o/d)? "
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read choice
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case "${choice}" in
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      a|A) exit 1;;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      o|O) sudo rm -rf "/var/lib/chroot/${target}"; break;;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      d|D) sudo rm -rf "/var/lib/chroot/${target}"      \
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "/usr/local/bin/${target%bit}"   \
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "/etc/schroot/mount-${target}"   \
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "/etc/schroot/script-${target}"
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           sudo sed -ni '/^[[]'"${target%bit}"']$/,${
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         :1;n;/^[[]/b2;b1;:2;p;n;b2};p' \
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "/etc/schroot/schroot.conf"
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           trap '' INT TERM QUIT HUP
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           trap '' EXIT
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           echo "Deleted!"
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           exit 0;;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    esac
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo mkdir -p /var/lib/chroot/"${target}"
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Offer to include additional standard repositories for Ubuntu-based chroots.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)alt_repos=
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" && {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while :; do
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "Would you like to add ${distname}-updates and ${distname}-security "
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf "to the chroot's sources.list (y/n)? "
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read alt_repos
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case "${alt_repos}" in
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y|Y)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alt_repos="y"
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      n|N)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    esac
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check for non-standard file system mount points and ask the user whether
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# they should be imported into the chroot environment
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# We limit to the first 26 mount points that much some basic heuristics,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# because a) that allows us to enumerate choices with a single character,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# and b) if we find more than 26 mount points, then these are probably
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# false-positives and something is very unusual about the system's
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# configuration. No need to spam the user with even more information that
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is likely completely irrelevant.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "${bind_mounts}" ]; then
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mounts="$(awk '$2 != "/" && $2 !~ "^/boot" && $2 !~ "^/home" &&
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 $2 !~ "^/media" && $2 !~ "^/run" &&
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ($3 ~ "ext[2-4]" || $3 == "reiserfs" || $3 == "btrfs" ||
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 $3 == "xfs" || $3 == "jfs" || $3 == "u?msdos" ||
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 $3 == "v?fat" || $3 == "hfs" || $3 == "ntfs" ||
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 $3 ~ "nfs[4-9]?" || $3 == "smbfs" || $3 == "cifs") {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   print $2
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 }' /proc/mounts |
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            head -n26)"
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -n "${mounts}" ]; then
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "You appear to have non-standard mount points that you"
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "might want to import into the chroot environment:"
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sel=
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while :; do
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Print a menu, listing all non-default mounts of local or network
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # file systems.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      j=1; for m in ${mounts}; do
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c="$(printf $(printf '\\%03o' $((64+$j))))"
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        echo "$sel" | grep -qs $c &&
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          state="mounted in chroot" || state="$(tput el)"
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printf "   $c) %-40s${state}\n" "$m"
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        j=$(($j+1))
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      done
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Allow user to interactively (de-)select any of the entries
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printf "Select mount points that you want to be included or press %s" \
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "SPACE to continue"
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      c="$(getkey | tr a-z A-Z)"
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      [ "$c" == " " ] && { echo; echo; break; }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if [ -z "$c" ] ||
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         [ "$c" '<' 'A' -o $(ord "$c") -gt $((64 + $(ord "$j"))) ]; then
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          # Invalid input, ring the console bell
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tput bel
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Toggle the selection for the given entry
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if echo "$sel" | grep -qs $c; then
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sel="$(printf "$sel" | sed "s/$c//")"
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sel="$sel$c"
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fi
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fi
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Reposition cursor to the top of the list of entries
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tput cuu $(($j + 1))
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    done
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  j=1; for m in ${mounts}; do
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c="$(chr $(($j + 64)))"
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if echo "$sel" | grep -qs $c; then
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bind_mounts="${bind_mounts}$m $m none rw,bind 0 0
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    j=$(($j+1))
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Remove stale entry from /etc/schroot/schroot.conf. Entries start
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# with the target name in square brackets, followed by an arbitrary
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# number of lines. The entry stops when either the end of file has
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# been reached, or when the beginning of a new target is encountered.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This means, we cannot easily match for a range of lines in
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# "sed". Instead, we actually have to iterate over each line and check
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# whether it is the beginning of a new entry.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sed -ni '/^[[]'"${target%bit}"']$/,${:1;n;/^[[]/b2;b1;:2;p;n;b2};p'       \
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /etc/schroot/schroot.conf
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Download base system. This takes some time
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "${mirror}" ]; then
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" &&
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   mirror="http://archive.ubuntu.com/ubuntu" ||
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   mirror="http://ftp.us.debian.org/debian"
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo ${http_proxy:+http_proxy="${http_proxy}"} debootstrap ${archflag} \
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "${distname}" "/var/lib/chroot/${target}"  "$mirror"
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add new entry to /etc/schroot/schroot.conf
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" &&
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  brand="Ubuntu" || brand="Debian"
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -z "${chroot_groups}" ]; then
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chroot_groups="${admin},$(id -gn)"
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Older versions of schroot wanted a "priority=" line, whereas recent
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# versions deprecate "priority=" and warn if they see it. We don't have
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a good feature test, but scanning for the string "priority=" in the
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# existing "schroot.conf" file is a good indication of what to do.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)priority=$(grep -qs 'priority=' /etc/schroot/schroot.conf &&
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           echo 'priority=3' || :)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sh -c 'cat >>/etc/schroot/schroot.conf' <<EOF
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[${target%bit}]
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)description=${brand} ${distname} ${arch}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)type=directory
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)directory=/var/lib/chroot/${target}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)users=root
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)groups=${chroot_groups}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)root-groups=${chroot_groups}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)personality=linux$([ "${arch}" != 64bit ] && echo 32)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)script-config=script-${target}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)${priority}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Set up a list of mount points that is specific to this
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# chroot environment.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sed '/^FSTAB=/s,"[^"]*","/etc/schroot/mount-'"${target}"'",' \
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         /etc/schroot/script-defaults |
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sh -c 'cat >/etc/schroot/script-'"${target}"
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sed '\,^/home[/[:space:]],s/\([,[:space:]]\)bind[[:space:]]/\1rbind /' \
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /etc/schroot/mount-defaults |
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sh -c 'cat > /etc/schroot/mount-'"${target}"
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add the extra mount points that the user told us about
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] &&
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printf "${bind_mounts}" |
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If this system has a "/media" mountpoint, import it into the chroot
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# environment. Most modern distributions use this mount point to
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# automatically mount devices such as CDROMs, USB sticks, etc...
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -d /media ] &&
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   ! grep -qs '^/media' /etc/schroot/mount-"${target}"; then
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo '/media /media none rw,rbind 0 0' |
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Share /dev/shm, /run and /run/shm.
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)grep -qs '^/dev/shm' /etc/schroot/mount-"${target}" ||
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo '/dev/shm /dev/shm none rw,bind 0 0' |
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if [ ! -d "/var/lib/chroot/${target}/run" ] &&
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   ! grep -qs '^/run' /etc/schroot/mount-"${target}"; then
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  echo '/run /run none rw,bind 0 0' |
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)fi
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if ! grep -qs '^/run/shm' /etc/schroot/mount-"${target}"; then
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { [ -d /run ] && echo '/run/shm /run/shm none rw,bind 0 0' ||
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   echo '/dev/shm /run/shm none rw,bind 0 0'; } |
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Set up a special directory that changes contents depending on the target
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# that is executing.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)d="$(readlink -f "${HOME}/chroot" 2>/dev/null || echo "${HOME}/chroot")"
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)s="${d}/.${target}"
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)echo "${s} ${d} none rw,bind 0 0" |
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sh -c 'cat >>/etc/schroot/mount-'"${target}"
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)mkdir -p "${s}"
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Install a helper script to launch commands in the chroot
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sh -c 'cat >/usr/local/bin/'"${target%bit}" <<'EOF'
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/bin/bash
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chroot="${0##*/}"
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wrap() {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Word-wrap the text passed-in on stdin. Optionally, on continuation lines
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # insert the same number of spaces as the number of characters in the
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # parameter(s) passed to this function.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # If the "fold" program cannot be found, or if the actual width of the
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # terminal cannot be determined, this function doesn't attempt to do any
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # wrapping.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local f="$(type -P fold)"
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -z "${f}" ] && { cat; return; }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local c="$(stty -a </dev/tty 2>/dev/null |
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             sed 's/.*columns[[:space:]]*\([0-9]*\).*/\1/;t;d')"
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -z "${c}" ] && { cat; return; }
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local i="$(echo "$*"|sed 's/./ /g')"
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local j="$(printf %s "${i}"|wc -c)"
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ "${c}" -gt "${j}" ]; then
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dd bs=1 count="${j}" 2>/dev/null
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "${f}" -sw "$((${c}-${j}))" | sed '2,$s/^/'"${i}"'/'
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "${f}" -sw "${c}"
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)help() {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "Usage ${0##*/} [-h|--help] [-c|--clean] [-C|--clean-all] [-l|--list] [--] args" | wrap "Usage ${0##*/} "
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "  help:      print this message"                                                | wrap "             "
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "  list:      list all known chroot environments"                                | wrap "             "
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "  clean:     remove all old chroot sessions for \"${chroot}\""                  | wrap "             "
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "  clean-all: remove all old chroot sessions for all environments"               | wrap "             "
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 0
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)clean() {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local s t rc
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc=0
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for s in $(schroot -l --all-sessions); do
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ -n "$1" ]; then
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      t="${s#session:}"
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      [ "${t#${chroot}-}" == "${t}" ] && continue
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ls -l /proc/*/{cwd,fd} 2>/dev/null |
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       fgrep -qs "/var/lib/schroot/mount/${t}"; then
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "Session \"${t}\" still has active users, not cleaning up" | wrap
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc=1
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo schroot -c "${s}" -e || rc=1
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit ${rc}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)list() {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for e in $(schroot -l); do
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    e="${e#chroot:}"
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -x "/usr/local/bin/${e}" ] || continue
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if schroot -l --all-sessions 2>/dev/null |
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       sed 's/^session://' |
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       grep -qs "^${e}-"; then
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "${e} is currently active"
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "${e}"
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exit 0
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)while [ "$#" -ne 0 ]; do
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  case "$1" in
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --)             shift; break;;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    -h|--help)      shift; help;;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    -l|--list)      shift; list;;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    -c|--clean)     shift; clean "${chroot}";;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    -C|--clean-all) shift; clean;;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *)              break;;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  esac
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
500ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Start a new chroot session and keep track of the session id. We inject this
501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# id into all processes that run inside the chroot. Unless they go out of their
502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# way to clear their environment, we can then later identify our child and
503ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# grand-child processes by scanning their environment.
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)session="$(schroot -c "${chroot}" -b)"
505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochexport CHROOT_SESSION_ID="${session}"
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ $# -eq 0 ]; then
508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # Run an interactive shell session
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  schroot -c "${session}" -r -p
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else
511ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # Run a command inside of the chroot environment
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  p="$1"; shift
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  schroot -c "${session}" -r -p "$p" -- "$@"
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rc=$?
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
517ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Compute the inode of the root directory inside of the chroot environment.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)i=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. |
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     awk '{ print $1 }') 2>/dev/null
520ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochother_pids=
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)while [ -n "$i" ]; do
522ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # Identify processes by the inode number of their root directory. Then
523ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # remove all processes that we know belong to other sessions. We use
524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # "sort | uniq -u" to do what amounts to a "set substraction operation".
525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  pids=$({ ls -id1 /proc/*/root/. 2>/dev/null |
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 t
528ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                 d';
529ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch         echo "${other_pids}";
530ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch         echo "${other_pids}"; } | sort | uniq -u) >/dev/null 2>&1
531ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # Kill all processes that are still left running in the session. This is
532ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # typically an assortment of daemon processes that were started
533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # automatically. They result in us being unable to tear down the session
534ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  # cleanly.
535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  [ -z "${pids}" ] && break
536ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for j in $pids; do
537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    # Unfortunately, the way that schroot sets up sessions has the
538ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    # side-effect of being unable to tell one session apart from another.
539ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    # This can result in us attempting to kill processes in other sessions.
540ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    # We make a best-effort to avoid doing so.
541ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    k="$( ( xargs -0 -n1 </proc/$j/environ ) 2>/dev/null |
542ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch         sed 's/^CHROOT_SESSION_ID=/x/;t1;d;:1;q')"
543ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if [ -n "${k}" -a "${k#x}" != "${session}" ]; then
544ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      other_pids="${other_pids}
545ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch${j}"
546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      continue
547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    fi
548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    kill -9 $pids
549ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  done
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# End the chroot session. This should clean up all temporary files. But if we
552ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# earlier failed to terminate all (daemon) processes inside of the session,
553ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# deleting the session could fail. When that happens, the user has to manually
554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# clean up the stale files by invoking us with "--clean" after having killed
555ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# all running processes.
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)schroot -c "${session}" -e
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exit $rc
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo chown root:root /usr/local/bin/"${target%bit}"
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo chmod 755 /usr/local/bin/"${target%bit}"
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add the standard Ubuntu update repositories if requested.
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ "${alt_repos}" = "y" -a \
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sed -i '/^deb .* [^ -]\+ main$/p
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             s/^\(deb .* [^ -]\+\) main/\1-security main/
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             p
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             t1
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             d
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             :1;s/-security main/-updates main/
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             t
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             d' "/var/lib/chroot/${target}/etc/apt/sources.list"
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add a few more repositories to the chroot
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sed -i 's/ main$/ main restricted universe multiverse/' \
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "/var/lib/chroot/${target}/etc/apt/sources.list"
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add the Ubuntu "partner" repository, if available
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   HEAD "http://archive.canonical.com/ubuntu/dists/${distname}/partner" \
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   >&/dev/null; then
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sh -c '
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "deb http://archive.canonical.com/ubuntu" \
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "'"${distname}"' partner" \
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      >>"/var/lib/chroot/'"${target}"'/etc/apt/sources.list"'
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add source repositories, if the user requested we do so
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)[ "${add_srcs}" = "y" -a \
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo sed -i '/^deb[^-]/p
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             s/^deb\([^-]\)/deb-src\1/' \
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "/var/lib/chroot/${target}/etc/apt/sources.list"
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Set apt proxy if host has set http_proxy
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -n "${http_proxy}" ]; then
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sh -c '
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "Acquire::http::proxy \"'"${http_proxy}"'\";" \
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        >>"/var/lib/chroot/'"${target}"'/etc/apt/apt.conf"'
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Update packages
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  apt-get update; apt-get -y dist-upgrade' || :
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Install a couple of missing packages
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for i in debian-keyring ubuntu-keyring locales sudo; do
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -d "/var/lib/chroot/${target}/usr/share/doc/$i" ] ||
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo "/usr/local/bin/${target%bit}" apt-get -y install "$i" || :
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)done
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Configure locales
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  l='"${LANG:-en_US}"'; l="${l%%.*}"
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -r /etc/locale.gen ] &&
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sed -i "s/^# \($l\)/\1/" /etc/locale.gen
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  locale-gen $LANG en_US en_US.UTF-8' || :
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Enable multi-arch support, if available
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo "/usr/local/bin/${target%bit}" dpkg --assert-multi-arch >&/dev/null &&
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo sed -i 's/ / [arch=amd64,i386] /' \
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "/var/lib/chroot/${target}/etc/apt/sources.list"
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -d /var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/ ] &&
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sudo "/usr/local/bin/${target%bit}" dpkg --add-architecture \
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) >&/dev/null ||
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    echo foreign-architecture \
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) |
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sudo sh -c \
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "cat >'/var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/multiarch'"
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Configure "sudo" package
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  egrep -qs '"'^$(id -nu) '"' /etc/sudoers ||
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo '"'$(id -nu) ALL=(ALL) ALL'"' >>/etc/sudoers'
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Install a few more commonly used packages
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo "/usr/local/bin/${target%bit}" apt-get -y install                         \
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  autoconf automake1.9 dpkg-dev g++-multilib gcc-multilib gdb less libtool     \
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strace
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If running a 32bit environment on a 64bit machine, install a few binaries
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# as 64bit. This is only done automatically if the chroot distro is the same as
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the host, otherwise there might be incompatibilities in build settings or
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# runtime dependencies. The user can force it with the '-c' flag.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)host_distro=$(grep -s DISTRIB_CODENAME /etc/lsb-release | \
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cut -d "=" -f 2)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ "${copy_64}" = "y" -o \
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "${host_distro}" = "${distname}" -a "${arch}" = 32bit ] && \
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file /bin/bash 2>/dev/null | grep -q x86-64; then
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  readlinepkg=$(sudo "/usr/local/bin/${target%bit}" sh -c \
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'apt-cache search "lib64readline.\$" | sort | tail -n 1 | cut -d " " -f 1')
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo "/usr/local/bin/${target%bit}" apt-get -y install                       \
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lib64expat1 lib64ncurses5 ${readlinepkg} lib64z1
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dep=
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for i in binutils gdb; do
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -d /usr/share/doc/"$i" ] || dep="$dep $i"
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [ -n "$dep" ] && sudo apt-get -y install $dep
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sudo mkdir -p "/var/lib/chroot/${target}/usr/local/lib/amd64"
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for i in libbfd libpython; do
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lib="$({ ldd /usr/bin/ld; ldd /usr/bin/gdb; } |
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           grep -s "$i" | awk '{ print $3 }')"
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ -n "$lib" -a -r "$lib" ]; then
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sudo cp "$lib" "/var/lib/chroot/${target}/usr/local/lib/amd64"
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for lib in libssl libcrypt; do
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for path in /usr/lib /usr/lib/x86_64-linux-gnu; do
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sudo cp $path/$lib* \
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "/var/lib/chroot/${target}/usr/local/lib/amd64/" >&/dev/null || :
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    done
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for i in gdb ld; do
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo cp /usr/bin/$i "/var/lib/chroot/${target}/usr/local/lib/amd64/"
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo sh -c "cat >'/var/lib/chroot/${target}/usr/local/bin/$i'" <<EOF
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/bin/sh
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exec /lib64/ld-linux-x86-64.so.2 --library-path /usr/local/lib/amd64 \
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /usr/local/lib/amd64/$i "\$@"
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sudo chmod 755 "/var/lib/chroot/${target}/usr/local/bin/$i"
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If the install-build-deps.sh script can be found, offer to run it now
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)script="$(dirname $(readlink -f "$0"))/install-build-deps.sh"
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ -x "${script}" ]; then
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while :; do
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "If you plan on building Chrome inside of the new chroot environment,"
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    echo "you now have to install the build dependencies. Do you want me to"
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf "start the script that does this for you (y/n)? "
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read install_deps
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case "${install_deps}" in
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y|Y)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        echo
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # We prefer running the script in-place, but this might not be
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # possible, if it lives on a network filesystem that denies
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # access to root.
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp_script=
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ! sudo /usr/local/bin/"${target%bit}" \
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sh -c "[ -x '${script}' ]" >&/dev/null; then
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tmp_script="/tmp/${script##*/}"
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cp "${script}" "${tmp_script}"
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fi
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # Some distributions automatically start an instance of the system-
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # wide dbus daemon, cron daemon or of the logging daemon, when
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # installing the Chrome build depencies. This prevents the chroot
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # session from being closed.  So, we always try to shut down any running
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # instance of dbus and rsyslog.
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sudo /usr/local/bin/"${target%bit}" sh -c "${script} --no-lib32;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              rc=$?;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              /etc/init.d/cron stop >/dev/null 2>&1 || :;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              /etc/init.d/rsyslog stop >/dev/null 2>&1 || :;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              /etc/init.d/dbus stop >/dev/null 2>&1 || :;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              exit $rc"
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc=$?
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        [ -n "${tmp_script}" ] && rm -f "${tmp_script}"
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        [ $rc -ne 0 ] && exit $rc
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      n|N)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ;;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    esac
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Check whether ~/chroot is on a (slow) network file system and offer to
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# relocate it. Also offer relocation, if the user appears to have multiple
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# spindles (as indicated by "${bind_mount}" being non-empty).
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# We only offer this option, if it doesn't look as if a chroot environment
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is currently active. Otherwise, relocation is unlikely to work and it
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# can be difficult for the user to recover from the failed attempt to relocate
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the ~/chroot directory.
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# We don't aim to solve this problem for every configuration,
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# but try to help with the common cases. For more advanced configuration
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# options, the user can always manually adjust things.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)mkdir -p "${HOME}/chroot/"
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [ ! -h "${HOME}/chroot" ] &&
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   ! egrep -qs '^[^[:space:]]*/chroot' /etc/fstab &&
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   { [ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] ||
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     is_network_drive "${HOME}/chroot"; } &&
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   ! egrep -qs '/var/lib/[^/]*chroot/.*/chroot' /proc/mounts; then
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "${HOME}/chroot is currently located on the same device as your"
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "home directory."
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "This might not be what you want. Do you want me to move it somewhere"
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  echo "else?"
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # If the computer has multiple spindles, many users configure all or part of
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # the secondary hard disk to be writable by the primary user of this machine.
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Make some reasonable effort to detect this type of configuration and
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # then offer a good location for where to put the ~/chroot directory.
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  suggest=
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for i in $(echo "${bind_mounts}"|cut -d ' ' -f 1); do
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if [ -d "$i" -a -w "$i" -a \( ! -a "$i/chroot" -o -w "$i/chroot/." \) ] &&
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ! is_network_drive "$i"; then
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      suggest="$i"
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for j in "$i/"*; do
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if [ -d "$j" -a -w "$j" -a \
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             \( ! -a "$j/chroot" -o -w "$j/chroot/." \) ] &&
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ! is_network_drive "$j"; then
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          suggest="$j"
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for k in "$j/"*; do
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if [ -d "$k" -a -w "$k" -a \
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 \( ! -a "$k/chroot" -o -w "$k/chroot/." \) ] &&
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               ! is_network_drive "$k"; then
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              suggest="$k"
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              break
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fi
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          done
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fi
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        [ -n "${suggest}" ] && break
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      done
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -n "${suggest}" ] && break
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def_suggest="${HOME}"
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if [ -n "${suggest}" ]; then
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # For home directories that reside on network drives, make our suggestion
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # the default option. For home directories that reside on a local drive,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # require that the user manually enters the new location.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if is_network_drive "${HOME}"; then
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      def_suggest="${suggest}"
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "A good location would probably be in \"${suggest}\""
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fi
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while :; do
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printf "Physical location [${def_suggest}]: "
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read dir
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ -z "${dir}" ] && dir="${def_suggest}"
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [ "${dir%%/}" == "${HOME%%/}" ] && break
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ! [ -d "${dir}" -a -w "${dir}" ] ||
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       [ -a "${dir}/chroot" -a ! -w "${dir}/chroot/." ]; then
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      echo "Cannot write to ${dir}/chroot. Please try again"
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mv "${HOME}/chroot" "${dir}/chroot"
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ln -s "${dir}/chroot" "${HOME}/chroot"
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for i in $(list_all_chroots); do
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sudo "$i" mkdir -p "${dir}/chroot"
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      done
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sudo sed -i "s,${HOME}/chroot,${dir}/chroot,g" /etc/schroot/mount-*
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fi
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fi
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Clean up package files
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sudo schroot -c "${target%bit}" -p -- apt-get clean
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sudo apt-get clean
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)trap '' INT TERM QUIT HUP
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)trap '' EXIT
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Let the user know what we did
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cat <<EOF
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Successfully installed ${distname} ${arch}
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)You can run programs inside of the chroot by invoking the
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"/usr/local/bin/${target%bit}" command.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)This command can be used with arguments, in order to just run a single
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)program inside of the chroot environment (e.g. "${target%bit} make chrome")
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)or without arguments, in order to run an interactive shell session inside
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)of the chroot environment.
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)If you need to run things as "root", you can use "sudo" (e.g. try
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"sudo ${target%bit} apt-get update").
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Your home directory is shared between the host and the chroot. But I
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)configured "${HOME}/chroot" to be private to the chroot environment.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)You can use it for files that need to differ between environments. This
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)would be a good place to store binaries that you have built from your
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)source files.
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)For Chrome, this probably means you want to make your "out" directory a
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)symbolic link that points somewhere inside of "${HOME}/chroot".
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)You still need to run "gclient runhooks" whenever you switch from building
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)outside of the chroot to inside of the chroot. But you will find that you
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)don't have to repeatedly erase and then completely rebuild all your object
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)and binary files.
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EOF
853