1*8975f5c5SAndroid Build Coastguard Worker#!/bin/bash -e 2*8975f5c5SAndroid Build Coastguard Worker 3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2012 The Chromium Authors 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker# This script installs Debian-derived distributions in a chroot environment. 8*8975f5c5SAndroid Build Coastguard Worker# It can for example be used to have an accurate 32bit build and test 9*8975f5c5SAndroid Build Coastguard Worker# environment when otherwise working on a 64bit machine. 10*8975f5c5SAndroid Build Coastguard Worker# N. B. it is unlikely that this script will ever work on anything other than a 11*8975f5c5SAndroid Build Coastguard Worker# Debian-derived system. 12*8975f5c5SAndroid Build Coastguard Worker 13*8975f5c5SAndroid Build Coastguard Worker# Older Debian based systems had both "admin" and "adm" groups, with "admin" 14*8975f5c5SAndroid Build Coastguard Worker# apparently being used in more places. Newer distributions have standardized 15*8975f5c5SAndroid Build Coastguard Worker# on just the "adm" group. Check /etc/group for the preferred name of the 16*8975f5c5SAndroid Build Coastguard Worker# administrator group. 17*8975f5c5SAndroid Build Coastguard Workeradmin=$(grep '^admin:' /etc/group >&/dev/null && echo admin || echo adm) 18*8975f5c5SAndroid Build Coastguard Worker 19*8975f5c5SAndroid Build Coastguard Workerusage() { 20*8975f5c5SAndroid Build Coastguard Worker echo "usage: ${0##*/} [-m mirror] [-g group,...] [-s] [-c]" 21*8975f5c5SAndroid Build Coastguard Worker echo "-b dir additional directories that should be bind mounted," 22*8975f5c5SAndroid Build Coastguard Worker echo ' or "NONE".' 23*8975f5c5SAndroid Build Coastguard Worker echo " Default: if local filesystems present, ask user for help" 24*8975f5c5SAndroid Build Coastguard Worker echo "-g group,... groups that can use the chroot unauthenticated" 25*8975f5c5SAndroid Build Coastguard Worker echo " Default: '${admin}' and current user's group ('$(id -gn)')" 26*8975f5c5SAndroid Build Coastguard Worker echo "-l List all installed chroot environments" 27*8975f5c5SAndroid Build Coastguard Worker echo "-m mirror an alternate repository mirror for package downloads" 28*8975f5c5SAndroid Build Coastguard Worker echo "-s configure default deb-srcs" 29*8975f5c5SAndroid Build Coastguard Worker echo "-c always copy 64bit helper binaries to 32bit chroot" 30*8975f5c5SAndroid Build Coastguard Worker echo "-h this help message" 31*8975f5c5SAndroid Build Coastguard Worker} 32*8975f5c5SAndroid Build Coastguard Worker 33*8975f5c5SAndroid Build Coastguard Workerprocess_opts() { 34*8975f5c5SAndroid Build Coastguard Worker local OPTNAME OPTIND OPTERR OPTARG 35*8975f5c5SAndroid Build Coastguard Worker while getopts ":b:g:lm:sch" OPTNAME; do 36*8975f5c5SAndroid Build Coastguard Worker case "$OPTNAME" in 37*8975f5c5SAndroid Build Coastguard Worker b) 38*8975f5c5SAndroid Build Coastguard Worker if [ "${OPTARG}" = "NONE" -a -z "${bind_mounts}" ]; then 39*8975f5c5SAndroid Build Coastguard Worker bind_mounts="${OPTARG}" 40*8975f5c5SAndroid Build Coastguard Worker else 41*8975f5c5SAndroid Build Coastguard Worker if [ "${bind_mounts}" = "NONE" -o "${OPTARG}" = "${OPTARG#/}" -o \ 42*8975f5c5SAndroid Build Coastguard Worker ! -d "${OPTARG}" ]; then 43*8975f5c5SAndroid Build Coastguard Worker echo "Invalid -b option(s)" 44*8975f5c5SAndroid Build Coastguard Worker usage 45*8975f5c5SAndroid Build Coastguard Worker exit 1 46*8975f5c5SAndroid Build Coastguard Worker fi 47*8975f5c5SAndroid Build Coastguard Worker bind_mounts="${bind_mounts} 48*8975f5c5SAndroid Build Coastguard Worker${OPTARG} ${OPTARG} none rw,bind 0 0" 49*8975f5c5SAndroid Build Coastguard Worker fi 50*8975f5c5SAndroid Build Coastguard Worker ;; 51*8975f5c5SAndroid Build Coastguard Worker g) 52*8975f5c5SAndroid Build Coastguard Worker [ -n "${OPTARG}" ] && 53*8975f5c5SAndroid Build Coastguard Worker chroot_groups="${chroot_groups}${chroot_groups:+,}${OPTARG}" 54*8975f5c5SAndroid Build Coastguard Worker ;; 55*8975f5c5SAndroid Build Coastguard Worker l) 56*8975f5c5SAndroid Build Coastguard Worker list_all_chroots 57*8975f5c5SAndroid Build Coastguard Worker exit 58*8975f5c5SAndroid Build Coastguard Worker ;; 59*8975f5c5SAndroid Build Coastguard Worker m) 60*8975f5c5SAndroid Build Coastguard Worker if [ -n "${mirror}" ]; then 61*8975f5c5SAndroid Build Coastguard Worker echo "You can only specify exactly one mirror location" 62*8975f5c5SAndroid Build Coastguard Worker usage 63*8975f5c5SAndroid Build Coastguard Worker exit 1 64*8975f5c5SAndroid Build Coastguard Worker fi 65*8975f5c5SAndroid Build Coastguard Worker mirror="$OPTARG" 66*8975f5c5SAndroid Build Coastguard Worker ;; 67*8975f5c5SAndroid Build Coastguard Worker s) 68*8975f5c5SAndroid Build Coastguard Worker add_srcs="y" 69*8975f5c5SAndroid Build Coastguard Worker ;; 70*8975f5c5SAndroid Build Coastguard Worker c) 71*8975f5c5SAndroid Build Coastguard Worker copy_64="y" 72*8975f5c5SAndroid Build Coastguard Worker ;; 73*8975f5c5SAndroid Build Coastguard Worker h) 74*8975f5c5SAndroid Build Coastguard Worker usage 75*8975f5c5SAndroid Build Coastguard Worker exit 0 76*8975f5c5SAndroid Build Coastguard Worker ;; 77*8975f5c5SAndroid Build Coastguard Worker \:) 78*8975f5c5SAndroid Build Coastguard Worker echo "'-$OPTARG' needs an argument." 79*8975f5c5SAndroid Build Coastguard Worker usage 80*8975f5c5SAndroid Build Coastguard Worker exit 1 81*8975f5c5SAndroid Build Coastguard Worker ;; 82*8975f5c5SAndroid Build Coastguard Worker *) 83*8975f5c5SAndroid Build Coastguard Worker echo "invalid command-line option: $OPTARG" 84*8975f5c5SAndroid Build Coastguard Worker usage 85*8975f5c5SAndroid Build Coastguard Worker exit 1 86*8975f5c5SAndroid Build Coastguard Worker ;; 87*8975f5c5SAndroid Build Coastguard Worker esac 88*8975f5c5SAndroid Build Coastguard Worker done 89*8975f5c5SAndroid Build Coastguard Worker 90*8975f5c5SAndroid Build Coastguard Worker if [ $# -ge ${OPTIND} ]; then 91*8975f5c5SAndroid Build Coastguard Worker eval echo "Unexpected command line argument: \${${OPTIND}}" 92*8975f5c5SAndroid Build Coastguard Worker usage 93*8975f5c5SAndroid Build Coastguard Worker exit 1 94*8975f5c5SAndroid Build Coastguard Worker fi 95*8975f5c5SAndroid Build Coastguard Worker} 96*8975f5c5SAndroid Build Coastguard Worker 97*8975f5c5SAndroid Build Coastguard Workerlist_all_chroots() { 98*8975f5c5SAndroid Build Coastguard Worker for i in /var/lib/chroot/*; do 99*8975f5c5SAndroid Build Coastguard Worker i="${i##*/}" 100*8975f5c5SAndroid Build Coastguard Worker [ "${i}" = "*" ] && continue 101*8975f5c5SAndroid Build Coastguard Worker [ -x "/usr/local/bin/${i%bit}" ] || continue 102*8975f5c5SAndroid Build Coastguard Worker grep -qs "^\[${i%bit}\]\$" /etc/schroot/schroot.conf || continue 103*8975f5c5SAndroid Build Coastguard Worker [ -r "/etc/schroot/script-${i}" -a \ 104*8975f5c5SAndroid Build Coastguard Worker -r "/etc/schroot/mount-${i}" ] || continue 105*8975f5c5SAndroid Build Coastguard Worker echo "${i%bit}" 106*8975f5c5SAndroid Build Coastguard Worker done 107*8975f5c5SAndroid Build Coastguard Worker} 108*8975f5c5SAndroid Build Coastguard Worker 109*8975f5c5SAndroid Build Coastguard Workergetkey() { 110*8975f5c5SAndroid Build Coastguard Worker ( 111*8975f5c5SAndroid Build Coastguard Worker trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT HUP 112*8975f5c5SAndroid Build Coastguard Worker stty -echo iuclc -icanon 2>/dev/null 113*8975f5c5SAndroid Build Coastguard Worker dd count=1 bs=1 2>/dev/null 114*8975f5c5SAndroid Build Coastguard Worker ) 115*8975f5c5SAndroid Build Coastguard Worker} 116*8975f5c5SAndroid Build Coastguard Worker 117*8975f5c5SAndroid Build Coastguard Workerchr() { 118*8975f5c5SAndroid Build Coastguard Worker printf "\\$(printf '%03o' "$1")" 119*8975f5c5SAndroid Build Coastguard Worker} 120*8975f5c5SAndroid Build Coastguard Worker 121*8975f5c5SAndroid Build Coastguard Workerord() { 122*8975f5c5SAndroid Build Coastguard Worker printf '%d' $(printf '%c' "$1" | od -tu1 -An) 123*8975f5c5SAndroid Build Coastguard Worker} 124*8975f5c5SAndroid Build Coastguard Worker 125*8975f5c5SAndroid Build Coastguard Workeris_network_drive() { 126*8975f5c5SAndroid Build Coastguard Worker stat -c %T -f "$1/" 2>/dev/null | 127*8975f5c5SAndroid Build Coastguard Worker egrep -qs '^nfs|cifs|smbfs' 128*8975f5c5SAndroid Build Coastguard Worker} 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard Worker# Check that we are running as a regular user 131*8975f5c5SAndroid Build Coastguard Worker[ "$(id -nu)" = root ] && { 132*8975f5c5SAndroid Build Coastguard Worker echo "Run this script as a regular user and provide your \"sudo\"" \ 133*8975f5c5SAndroid Build Coastguard Worker "password if requested" >&2 134*8975f5c5SAndroid Build Coastguard Worker exit 1 135*8975f5c5SAndroid Build Coastguard Worker} 136*8975f5c5SAndroid Build Coastguard Worker 137*8975f5c5SAndroid Build Coastguard Workerprocess_opts "$@" 138*8975f5c5SAndroid Build Coastguard Worker 139*8975f5c5SAndroid Build Coastguard Workerecho "This script will help you through the process of installing a" 140*8975f5c5SAndroid Build Coastguard Workerecho "Debian or Ubuntu distribution in a chroot environment. You will" 141*8975f5c5SAndroid Build Coastguard Workerecho "have to provide your \"sudo\" password when requested." 142*8975f5c5SAndroid Build Coastguard Workerecho 143*8975f5c5SAndroid Build Coastguard Worker 144*8975f5c5SAndroid Build Coastguard Worker# Error handler 145*8975f5c5SAndroid Build Coastguard Workertrap 'exit 1' INT TERM QUIT HUP 146*8975f5c5SAndroid Build Coastguard Workertrap 'sudo apt-get clean; tput bel; echo; echo Failed' EXIT 147*8975f5c5SAndroid Build Coastguard Worker 148*8975f5c5SAndroid Build Coastguard Worker# Install any missing applications that this script relies on. If these packages 149*8975f5c5SAndroid Build Coastguard Worker# are already installed, don't force another "apt-get install". That would 150*8975f5c5SAndroid Build Coastguard Worker# prevent them from being auto-removed, if they ever become eligible for that. 151*8975f5c5SAndroid Build Coastguard Worker# And as this script only needs the packages once, there is no good reason to 152*8975f5c5SAndroid Build Coastguard Worker# introduce a hard dependency on things such as dchroot and debootstrap. 153*8975f5c5SAndroid Build Coastguard Workerdep= 154*8975f5c5SAndroid Build Coastguard Workerfor i in dchroot debootstrap libwww-perl; do 155*8975f5c5SAndroid Build Coastguard Worker [ -d /usr/share/doc/"$i" ] || dep="$dep $i" 156*8975f5c5SAndroid Build Coastguard Workerdone 157*8975f5c5SAndroid Build Coastguard Worker[ -n "$dep" ] && sudo apt-get -y install $dep 158*8975f5c5SAndroid Build Coastguard Workersudo apt-get -y install schroot 159*8975f5c5SAndroid Build Coastguard Worker 160*8975f5c5SAndroid Build Coastguard Worker# Create directory for chroot 161*8975f5c5SAndroid Build Coastguard Workersudo mkdir -p /var/lib/chroot 162*8975f5c5SAndroid Build Coastguard Worker 163*8975f5c5SAndroid Build Coastguard Worker# Find chroot environments that can be installed with debootstrap 164*8975f5c5SAndroid Build Coastguard Workertargets="$(cd /usr/share/debootstrap/scripts 165*8975f5c5SAndroid Build Coastguard Worker ls | grep '^[a-z]*$')" 166*8975f5c5SAndroid Build Coastguard Worker 167*8975f5c5SAndroid Build Coastguard Worker# Ask user to pick one of the available targets 168*8975f5c5SAndroid Build Coastguard Workerecho "The following targets are available to be installed in a chroot:" 169*8975f5c5SAndroid Build Coastguard Workerj=1; for i in $targets; do 170*8975f5c5SAndroid Build Coastguard Worker printf '%4d: %s\n' "$j" "$i" 171*8975f5c5SAndroid Build Coastguard Worker j=$(($j+1)) 172*8975f5c5SAndroid Build Coastguard Workerdone 173*8975f5c5SAndroid Build Coastguard Workerwhile :; do 174*8975f5c5SAndroid Build Coastguard Worker printf "Which target would you like to install: " 175*8975f5c5SAndroid Build Coastguard Worker read n 176*8975f5c5SAndroid Build Coastguard Worker [ "$n" -gt 0 -a "$n" -lt "$j" ] >&/dev/null && break 177*8975f5c5SAndroid Build Coastguard Workerdone 178*8975f5c5SAndroid Build Coastguard Workerj=1; for i in $targets; do 179*8975f5c5SAndroid Build Coastguard Worker [ "$j" -eq "$n" ] && { distname="$i"; break; } 180*8975f5c5SAndroid Build Coastguard Worker j=$(($j+1)) 181*8975f5c5SAndroid Build Coastguard Workerdone 182*8975f5c5SAndroid Build Coastguard Workerecho 183*8975f5c5SAndroid Build Coastguard Worker 184*8975f5c5SAndroid Build Coastguard Worker# On x86-64, ask whether the user wants to install x86-32 or x86-64 185*8975f5c5SAndroid Build Coastguard Workerarchflag= 186*8975f5c5SAndroid Build Coastguard Workerarch= 187*8975f5c5SAndroid Build Coastguard Workerif [ "$(uname -m)" = x86_64 ]; then 188*8975f5c5SAndroid Build Coastguard Worker while :; do 189*8975f5c5SAndroid Build Coastguard Worker echo "You are running a 64bit kernel. This allows you to install either a" 190*8975f5c5SAndroid Build Coastguard Worker printf "32bit or a 64bit chroot environment. %s" \ 191*8975f5c5SAndroid Build Coastguard Worker "Which one do you want (32, 64) " 192*8975f5c5SAndroid Build Coastguard Worker read arch 193*8975f5c5SAndroid Build Coastguard Worker [ "${arch}" == 32 -o "${arch}" == 64 ] && break 194*8975f5c5SAndroid Build Coastguard Worker done 195*8975f5c5SAndroid Build Coastguard Worker [ "${arch}" == 32 ] && archflag="--arch i386" || archflag="--arch amd64" 196*8975f5c5SAndroid Build Coastguard Worker arch="${arch}bit" 197*8975f5c5SAndroid Build Coastguard Worker echo 198*8975f5c5SAndroid Build Coastguard Workerfi 199*8975f5c5SAndroid Build Coastguard Workertarget="${distname}${arch}" 200*8975f5c5SAndroid Build Coastguard Worker 201*8975f5c5SAndroid Build Coastguard Worker# Don't accidentally overwrite an existing installation 202*8975f5c5SAndroid Build Coastguard Worker[ -d /var/lib/chroot/"${target}" ] && { 203*8975f5c5SAndroid Build Coastguard Worker while :; do 204*8975f5c5SAndroid Build Coastguard Worker echo "This chroot already exists on your machine." 205*8975f5c5SAndroid Build Coastguard Worker if schroot -l --all-sessions 2>&1 | 206*8975f5c5SAndroid Build Coastguard Worker sed 's/^session://' | 207*8975f5c5SAndroid Build Coastguard Worker grep -qs "^${target%bit}-"; then 208*8975f5c5SAndroid Build Coastguard Worker echo "And it appears to be in active use. Terminate all programs that" 209*8975f5c5SAndroid Build Coastguard Worker echo "are currently using the chroot environment and then re-run this" 210*8975f5c5SAndroid Build Coastguard Worker echo "script." 211*8975f5c5SAndroid Build Coastguard Worker echo "If you still get an error message, you might have stale mounts" 212*8975f5c5SAndroid Build Coastguard Worker echo "that you forgot to delete. You can always clean up mounts by" 213*8975f5c5SAndroid Build Coastguard Worker echo "executing \"${target%bit} -c\"." 214*8975f5c5SAndroid Build Coastguard Worker exit 1 215*8975f5c5SAndroid Build Coastguard Worker fi 216*8975f5c5SAndroid Build Coastguard Worker echo "I can abort installation, I can overwrite the existing chroot," 217*8975f5c5SAndroid Build Coastguard Worker echo "or I can delete the old one and then exit. What would you like to" 218*8975f5c5SAndroid Build Coastguard Worker printf "do (a/o/d)? " 219*8975f5c5SAndroid Build Coastguard Worker read choice 220*8975f5c5SAndroid Build Coastguard Worker case "${choice}" in 221*8975f5c5SAndroid Build Coastguard Worker a|A) exit 1;; 222*8975f5c5SAndroid Build Coastguard Worker o|O) sudo rm -rf "/var/lib/chroot/${target}"; break;; 223*8975f5c5SAndroid Build Coastguard Worker d|D) sudo rm -rf "/var/lib/chroot/${target}" \ 224*8975f5c5SAndroid Build Coastguard Worker "/usr/local/bin/${target%bit}" \ 225*8975f5c5SAndroid Build Coastguard Worker "/etc/schroot/mount-${target}" \ 226*8975f5c5SAndroid Build Coastguard Worker "/etc/schroot/script-${target}" \ 227*8975f5c5SAndroid Build Coastguard Worker "/etc/schroot/${target}" 228*8975f5c5SAndroid Build Coastguard Worker sudo sed -ni '/^[[]'"${target%bit}"']$/,${ 229*8975f5c5SAndroid Build Coastguard Worker :1;n;/^[[]/b2;b1;:2;p;n;b2};p' \ 230*8975f5c5SAndroid Build Coastguard Worker "/etc/schroot/schroot.conf" 231*8975f5c5SAndroid Build Coastguard Worker trap '' INT TERM QUIT HUP 232*8975f5c5SAndroid Build Coastguard Worker trap '' EXIT 233*8975f5c5SAndroid Build Coastguard Worker echo "Deleted!" 234*8975f5c5SAndroid Build Coastguard Worker exit 0;; 235*8975f5c5SAndroid Build Coastguard Worker esac 236*8975f5c5SAndroid Build Coastguard Worker done 237*8975f5c5SAndroid Build Coastguard Worker echo 238*8975f5c5SAndroid Build Coastguard Worker} 239*8975f5c5SAndroid Build Coastguard Workersudo mkdir -p /var/lib/chroot/"${target}" 240*8975f5c5SAndroid Build Coastguard Worker 241*8975f5c5SAndroid Build Coastguard Worker# Offer to include additional standard repositories for Ubuntu-based chroots. 242*8975f5c5SAndroid Build Coastguard Workeralt_repos= 243*8975f5c5SAndroid Build Coastguard Workergrep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" && { 244*8975f5c5SAndroid Build Coastguard Worker while :; do 245*8975f5c5SAndroid Build Coastguard Worker echo "Would you like to add ${distname}-updates and ${distname}-security " 246*8975f5c5SAndroid Build Coastguard Worker printf "to the chroot's sources.list (y/n)? " 247*8975f5c5SAndroid Build Coastguard Worker read alt_repos 248*8975f5c5SAndroid Build Coastguard Worker case "${alt_repos}" in 249*8975f5c5SAndroid Build Coastguard Worker y|Y) 250*8975f5c5SAndroid Build Coastguard Worker alt_repos="y" 251*8975f5c5SAndroid Build Coastguard Worker break 252*8975f5c5SAndroid Build Coastguard Worker ;; 253*8975f5c5SAndroid Build Coastguard Worker n|N) 254*8975f5c5SAndroid Build Coastguard Worker break 255*8975f5c5SAndroid Build Coastguard Worker ;; 256*8975f5c5SAndroid Build Coastguard Worker esac 257*8975f5c5SAndroid Build Coastguard Worker done 258*8975f5c5SAndroid Build Coastguard Worker echo 259*8975f5c5SAndroid Build Coastguard Worker} 260*8975f5c5SAndroid Build Coastguard Worker 261*8975f5c5SAndroid Build Coastguard Worker# Check for non-standard file system mount points and ask the user whether 262*8975f5c5SAndroid Build Coastguard Worker# they should be imported into the chroot environment 263*8975f5c5SAndroid Build Coastguard Worker# We limit to the first 26 mount points that much some basic heuristics, 264*8975f5c5SAndroid Build Coastguard Worker# because a) that allows us to enumerate choices with a single character, 265*8975f5c5SAndroid Build Coastguard Worker# and b) if we find more than 26 mount points, then these are probably 266*8975f5c5SAndroid Build Coastguard Worker# false-positives and something is very unusual about the system's 267*8975f5c5SAndroid Build Coastguard Worker# configuration. No need to spam the user with even more information that 268*8975f5c5SAndroid Build Coastguard Worker# is likely completely irrelevant. 269*8975f5c5SAndroid Build Coastguard Workerif [ -z "${bind_mounts}" ]; then 270*8975f5c5SAndroid Build Coastguard Worker mounts="$(awk '$2 != "/" && $2 !~ "^/boot" && $2 !~ "^/home" && 271*8975f5c5SAndroid Build Coastguard Worker $2 !~ "^/media" && $2 !~ "^/run" && 272*8975f5c5SAndroid Build Coastguard Worker ($3 ~ "ext[2-4]" || $3 == "reiserfs" || $3 == "btrfs" || 273*8975f5c5SAndroid Build Coastguard Worker $3 == "xfs" || $3 == "jfs" || $3 == "u?msdos" || 274*8975f5c5SAndroid Build Coastguard Worker $3 == "v?fat" || $3 == "hfs" || $3 == "ntfs" || 275*8975f5c5SAndroid Build Coastguard Worker $3 ~ "nfs[4-9]?" || $3 == "smbfs" || $3 == "cifs") { 276*8975f5c5SAndroid Build Coastguard Worker print $2 277*8975f5c5SAndroid Build Coastguard Worker }' /proc/mounts | 278*8975f5c5SAndroid Build Coastguard Worker head -n26)" 279*8975f5c5SAndroid Build Coastguard Worker if [ -n "${mounts}" ]; then 280*8975f5c5SAndroid Build Coastguard Worker echo "You appear to have non-standard mount points that you" 281*8975f5c5SAndroid Build Coastguard Worker echo "might want to import into the chroot environment:" 282*8975f5c5SAndroid Build Coastguard Worker echo 283*8975f5c5SAndroid Build Coastguard Worker sel= 284*8975f5c5SAndroid Build Coastguard Worker while :; do 285*8975f5c5SAndroid Build Coastguard Worker # Print a menu, listing all non-default mounts of local or network 286*8975f5c5SAndroid Build Coastguard Worker # file systems. 287*8975f5c5SAndroid Build Coastguard Worker j=1; for m in ${mounts}; do 288*8975f5c5SAndroid Build Coastguard Worker c="$(printf $(printf '\\%03o' $((64+$j))))" 289*8975f5c5SAndroid Build Coastguard Worker echo "$sel" | grep -qs $c && 290*8975f5c5SAndroid Build Coastguard Worker state="mounted in chroot" || state="$(tput el)" 291*8975f5c5SAndroid Build Coastguard Worker printf " $c) %-40s${state}\n" "$m" 292*8975f5c5SAndroid Build Coastguard Worker j=$(($j+1)) 293*8975f5c5SAndroid Build Coastguard Worker done 294*8975f5c5SAndroid Build Coastguard Worker # Allow user to interactively (de-)select any of the entries 295*8975f5c5SAndroid Build Coastguard Worker echo 296*8975f5c5SAndroid Build Coastguard Worker printf "Select mount points that you want to be included or press %s" \ 297*8975f5c5SAndroid Build Coastguard Worker "SPACE to continue" 298*8975f5c5SAndroid Build Coastguard Worker c="$(getkey | tr a-z A-Z)" 299*8975f5c5SAndroid Build Coastguard Worker [ "$c" == " " ] && { echo; echo; break; } 300*8975f5c5SAndroid Build Coastguard Worker if [ -z "$c" ] || 301*8975f5c5SAndroid Build Coastguard Worker [ "$c" '<' 'A' -o $(ord "$c") -gt $((64 + $(ord "$j"))) ]; then 302*8975f5c5SAndroid Build Coastguard Worker # Invalid input, ring the console bell 303*8975f5c5SAndroid Build Coastguard Worker tput bel 304*8975f5c5SAndroid Build Coastguard Worker else 305*8975f5c5SAndroid Build Coastguard Worker # Toggle the selection for the given entry 306*8975f5c5SAndroid Build Coastguard Worker if echo "$sel" | grep -qs $c; then 307*8975f5c5SAndroid Build Coastguard Worker sel="$(printf "$sel" | sed "s/$c//")" 308*8975f5c5SAndroid Build Coastguard Worker else 309*8975f5c5SAndroid Build Coastguard Worker sel="$sel$c" 310*8975f5c5SAndroid Build Coastguard Worker fi 311*8975f5c5SAndroid Build Coastguard Worker fi 312*8975f5c5SAndroid Build Coastguard Worker # Reposition cursor to the top of the list of entries 313*8975f5c5SAndroid Build Coastguard Worker tput cuu $(($j + 1)) 314*8975f5c5SAndroid Build Coastguard Worker echo 315*8975f5c5SAndroid Build Coastguard Worker done 316*8975f5c5SAndroid Build Coastguard Worker fi 317*8975f5c5SAndroid Build Coastguard Worker j=1; for m in ${mounts}; do 318*8975f5c5SAndroid Build Coastguard Worker c="$(chr $(($j + 64)))" 319*8975f5c5SAndroid Build Coastguard Worker if echo "$sel" | grep -qs $c; then 320*8975f5c5SAndroid Build Coastguard Worker bind_mounts="${bind_mounts}$m $m none rw,bind 0 0 321*8975f5c5SAndroid Build Coastguard Worker" 322*8975f5c5SAndroid Build Coastguard Worker fi 323*8975f5c5SAndroid Build Coastguard Worker j=$(($j+1)) 324*8975f5c5SAndroid Build Coastguard Worker done 325*8975f5c5SAndroid Build Coastguard Workerfi 326*8975f5c5SAndroid Build Coastguard Worker 327*8975f5c5SAndroid Build Coastguard Worker# Remove stale entry from /etc/schroot/schroot.conf. Entries start 328*8975f5c5SAndroid Build Coastguard Worker# with the target name in square brackets, followed by an arbitrary 329*8975f5c5SAndroid Build Coastguard Worker# number of lines. The entry stops when either the end of file has 330*8975f5c5SAndroid Build Coastguard Worker# been reached, or when the beginning of a new target is encountered. 331*8975f5c5SAndroid Build Coastguard Worker# This means, we cannot easily match for a range of lines in 332*8975f5c5SAndroid Build Coastguard Worker# "sed". Instead, we actually have to iterate over each line and check 333*8975f5c5SAndroid Build Coastguard Worker# whether it is the beginning of a new entry. 334*8975f5c5SAndroid Build Coastguard Workersudo sed -ni '/^[[]'"${target%bit}"']$/,${:1;n;/^[[]/b2;b1;:2;p;n;b2};p' \ 335*8975f5c5SAndroid Build Coastguard Worker /etc/schroot/schroot.conf 336*8975f5c5SAndroid Build Coastguard Worker 337*8975f5c5SAndroid Build Coastguard Worker# Download base system. This takes some time 338*8975f5c5SAndroid Build Coastguard Workerif [ -z "${mirror}" ]; then 339*8975f5c5SAndroid Build Coastguard Worker grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" && 340*8975f5c5SAndroid Build Coastguard Worker mirror="http://archive.ubuntu.com/ubuntu" || 341*8975f5c5SAndroid Build Coastguard Worker mirror="http://ftp.us.debian.org/debian" 342*8975f5c5SAndroid Build Coastguard Workerfi 343*8975f5c5SAndroid Build Coastguard Worker 344*8975f5c5SAndroid Build Coastguard Workersudo ${http_proxy:+http_proxy="${http_proxy}"} debootstrap ${archflag} \ 345*8975f5c5SAndroid Build Coastguard Worker "${distname}" "/var/lib/chroot/${target}" "$mirror" 346*8975f5c5SAndroid Build Coastguard Worker 347*8975f5c5SAndroid Build Coastguard Worker# Add new entry to /etc/schroot/schroot.conf 348*8975f5c5SAndroid Build Coastguard Workergrep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" && 349*8975f5c5SAndroid Build Coastguard Worker brand="Ubuntu" || brand="Debian" 350*8975f5c5SAndroid Build Coastguard Workerif [ -z "${chroot_groups}" ]; then 351*8975f5c5SAndroid Build Coastguard Worker chroot_groups="${admin},$(id -gn)" 352*8975f5c5SAndroid Build Coastguard Workerfi 353*8975f5c5SAndroid Build Coastguard Worker 354*8975f5c5SAndroid Build Coastguard Workerif [ -d '/etc/schroot/default' ]; then 355*8975f5c5SAndroid Build Coastguard Worker new_version=1 356*8975f5c5SAndroid Build Coastguard Worker fstab="/etc/schroot/${target}/fstab" 357*8975f5c5SAndroid Build Coastguard Workerelse 358*8975f5c5SAndroid Build Coastguard Worker new_version=0 359*8975f5c5SAndroid Build Coastguard Worker fstab="/etc/schroot/mount-${target}" 360*8975f5c5SAndroid Build Coastguard Workerfi 361*8975f5c5SAndroid Build Coastguard Worker 362*8975f5c5SAndroid Build Coastguard Workerif [ "$new_version" = "1" ]; then 363*8975f5c5SAndroid Build Coastguard Worker sudo cp -ar /etc/schroot/default /etc/schroot/${target} 364*8975f5c5SAndroid Build Coastguard Worker 365*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>/etc/schroot/schroot.conf' <<EOF 366*8975f5c5SAndroid Build Coastguard Worker[${target%bit}] 367*8975f5c5SAndroid Build Coastguard Workerdescription=${brand} ${distname} ${arch} 368*8975f5c5SAndroid Build Coastguard Workertype=directory 369*8975f5c5SAndroid Build Coastguard Workerdirectory=/var/lib/chroot/${target} 370*8975f5c5SAndroid Build Coastguard Workerusers=root 371*8975f5c5SAndroid Build Coastguard Workergroups=${chroot_groups} 372*8975f5c5SAndroid Build Coastguard Workerroot-groups=${chroot_groups} 373*8975f5c5SAndroid Build Coastguard Workerpersonality=linux$([ "${arch}" != 64bit ] && echo 32) 374*8975f5c5SAndroid Build Coastguard Workerprofile=${target} 375*8975f5c5SAndroid Build Coastguard Worker 376*8975f5c5SAndroid Build Coastguard WorkerEOF 377*8975f5c5SAndroid Build Coastguard Worker [ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] && 378*8975f5c5SAndroid Build Coastguard Worker printf "${bind_mounts}" | 379*8975f5c5SAndroid Build Coastguard Worker sudo sh -c "cat >>${fstab}" 380*8975f5c5SAndroid Build Coastguard Workerelse 381*8975f5c5SAndroid Build Coastguard Worker # Older versions of schroot wanted a "priority=" line, whereas recent 382*8975f5c5SAndroid Build Coastguard Worker # versions deprecate "priority=" and warn if they see it. We don't have 383*8975f5c5SAndroid Build Coastguard Worker # a good feature test, but scanning for the string "priority=" in the 384*8975f5c5SAndroid Build Coastguard Worker # existing "schroot.conf" file is a good indication of what to do. 385*8975f5c5SAndroid Build Coastguard Worker priority=$(grep -qs 'priority=' /etc/schroot/schroot.conf && 386*8975f5c5SAndroid Build Coastguard Worker echo 'priority=3' || :) 387*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>/etc/schroot/schroot.conf' <<EOF 388*8975f5c5SAndroid Build Coastguard Worker[${target%bit}] 389*8975f5c5SAndroid Build Coastguard Workerdescription=${brand} ${distname} ${arch} 390*8975f5c5SAndroid Build Coastguard Workertype=directory 391*8975f5c5SAndroid Build Coastguard Workerdirectory=/var/lib/chroot/${target} 392*8975f5c5SAndroid Build Coastguard Workerusers=root 393*8975f5c5SAndroid Build Coastguard Workergroups=${chroot_groups} 394*8975f5c5SAndroid Build Coastguard Workerroot-groups=${chroot_groups} 395*8975f5c5SAndroid Build Coastguard Workerpersonality=linux$([ "${arch}" != 64bit ] && echo 32) 396*8975f5c5SAndroid Build Coastguard Workerscript-config=script-${target} 397*8975f5c5SAndroid Build Coastguard Worker${priority} 398*8975f5c5SAndroid Build Coastguard Worker 399*8975f5c5SAndroid Build Coastguard WorkerEOF 400*8975f5c5SAndroid Build Coastguard Worker 401*8975f5c5SAndroid Build Coastguard Worker # Set up a list of mount points that is specific to this 402*8975f5c5SAndroid Build Coastguard Worker # chroot environment. 403*8975f5c5SAndroid Build Coastguard Worker sed '/^FSTAB=/s,"[^"]*","'"${fstab}"'",' \ 404*8975f5c5SAndroid Build Coastguard Worker /etc/schroot/script-defaults | 405*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >/etc/schroot/script-'"${target}" 406*8975f5c5SAndroid Build Coastguard Worker sed '\,^/home[/[:space:]],s/\([,[:space:]]\)bind[[:space:]]/\1rbind /' \ 407*8975f5c5SAndroid Build Coastguard Worker /etc/schroot/mount-defaults | 408*8975f5c5SAndroid Build Coastguard Worker sudo sh -c "cat > ${fstab}" 409*8975f5c5SAndroid Build Coastguard Workerfi 410*8975f5c5SAndroid Build Coastguard Worker 411*8975f5c5SAndroid Build Coastguard Worker# Add the extra mount points that the user told us about 412*8975f5c5SAndroid Build Coastguard Worker[ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] && 413*8975f5c5SAndroid Build Coastguard Worker printf "${bind_mounts}" | 414*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${fstab}" 415*8975f5c5SAndroid Build Coastguard Worker 416*8975f5c5SAndroid Build Coastguard Worker# If this system has a "/media" mountpoint, import it into the chroot 417*8975f5c5SAndroid Build Coastguard Worker# environment. Most modern distributions use this mount point to 418*8975f5c5SAndroid Build Coastguard Worker# automatically mount devices such as CDROMs, USB sticks, etc... 419*8975f5c5SAndroid Build Coastguard Workerif [ -d /media ] && 420*8975f5c5SAndroid Build Coastguard Worker ! grep -qs '^/media' "${fstab}"; then 421*8975f5c5SAndroid Build Coastguard Worker echo '/media /media none rw,rbind 0 0' | 422*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${fstab}" 423*8975f5c5SAndroid Build Coastguard Workerfi 424*8975f5c5SAndroid Build Coastguard Worker 425*8975f5c5SAndroid Build Coastguard Worker# Share /dev/shm, /run and /run/shm. 426*8975f5c5SAndroid Build Coastguard Workergrep -qs '^/dev/shm' "${fstab}" || 427*8975f5c5SAndroid Build Coastguard Worker echo '/dev/shm /dev/shm none rw,bind 0 0' | 428*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${fstab}" 429*8975f5c5SAndroid Build Coastguard Workerif [ ! -d "/var/lib/chroot/${target}/run" ] && 430*8975f5c5SAndroid Build Coastguard Worker ! grep -qs '^/run' "${fstab}"; then 431*8975f5c5SAndroid Build Coastguard Worker echo '/run /run none rw,bind 0 0' | 432*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${fstab}" 433*8975f5c5SAndroid Build Coastguard Workerfi 434*8975f5c5SAndroid Build Coastguard Workerif ! grep -qs '^/run/shm' "${fstab}"; then 435*8975f5c5SAndroid Build Coastguard Worker { [ -d /run ] && echo '/run/shm /run/shm none rw,bind 0 0' || 436*8975f5c5SAndroid Build Coastguard Worker echo '/dev/shm /run/shm none rw,bind 0 0'; } | 437*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${fstab}" 438*8975f5c5SAndroid Build Coastguard Workerfi 439*8975f5c5SAndroid Build Coastguard Worker 440*8975f5c5SAndroid Build Coastguard Worker# Set up a special directory that changes contents depending on the target 441*8975f5c5SAndroid Build Coastguard Worker# that is executing. 442*8975f5c5SAndroid Build Coastguard Workerd="$(readlink -f "${HOME}/chroot" 2>/dev/null || echo "${HOME}/chroot")" 443*8975f5c5SAndroid Build Coastguard Workers="${d}/.${target}" 444*8975f5c5SAndroid Build Coastguard Workerecho "${s} ${d} none rw,bind 0 0" | 445*8975f5c5SAndroid Build Coastguard Worker sudo sh -c 'cat >>'"${target}" 446*8975f5c5SAndroid Build Coastguard Workermkdir -p "${s}" 447*8975f5c5SAndroid Build Coastguard Worker 448*8975f5c5SAndroid Build Coastguard Worker# Install a helper script to launch commands in the chroot 449*8975f5c5SAndroid Build Coastguard Workersudo sh -c 'cat >/usr/local/bin/'"${target%bit}" <<'EOF' 450*8975f5c5SAndroid Build Coastguard Worker#!/bin/bash 451*8975f5c5SAndroid Build Coastguard Worker 452*8975f5c5SAndroid Build Coastguard Workerchroot="${0##*/}" 453*8975f5c5SAndroid Build Coastguard Worker 454*8975f5c5SAndroid Build Coastguard Workerwrap() { 455*8975f5c5SAndroid Build Coastguard Worker # Word-wrap the text passed-in on stdin. Optionally, on continuation lines 456*8975f5c5SAndroid Build Coastguard Worker # insert the same number of spaces as the number of characters in the 457*8975f5c5SAndroid Build Coastguard Worker # parameter(s) passed to this function. 458*8975f5c5SAndroid Build Coastguard Worker # If the "fold" program cannot be found, or if the actual width of the 459*8975f5c5SAndroid Build Coastguard Worker # terminal cannot be determined, this function doesn't attempt to do any 460*8975f5c5SAndroid Build Coastguard Worker # wrapping. 461*8975f5c5SAndroid Build Coastguard Worker local f="$(type -P fold)" 462*8975f5c5SAndroid Build Coastguard Worker [ -z "${f}" ] && { cat; return; } 463*8975f5c5SAndroid Build Coastguard Worker local c="$(stty -a </dev/tty 2>/dev/null | 464*8975f5c5SAndroid Build Coastguard Worker sed 's/.*columns[[:space:]]*\([0-9]*\).*/\1/;t;d')" 465*8975f5c5SAndroid Build Coastguard Worker [ -z "${c}" ] && { cat; return; } 466*8975f5c5SAndroid Build Coastguard Worker local i="$(echo "$*"|sed 's/./ /g')" 467*8975f5c5SAndroid Build Coastguard Worker local j="$(printf %s "${i}"|wc -c)" 468*8975f5c5SAndroid Build Coastguard Worker if [ "${c}" -gt "${j}" ]; then 469*8975f5c5SAndroid Build Coastguard Worker dd bs=1 count="${j}" 2>/dev/null 470*8975f5c5SAndroid Build Coastguard Worker "${f}" -sw "$((${c}-${j}))" | sed '2,$s/^/'"${i}"'/' 471*8975f5c5SAndroid Build Coastguard Worker else 472*8975f5c5SAndroid Build Coastguard Worker "${f}" -sw "${c}" 473*8975f5c5SAndroid Build Coastguard Worker fi 474*8975f5c5SAndroid Build Coastguard Worker} 475*8975f5c5SAndroid Build Coastguard Worker 476*8975f5c5SAndroid Build Coastguard Workerhelp() { 477*8975f5c5SAndroid Build Coastguard Worker echo "Usage ${0##*/} [-h|--help] [-c|--clean] [-C|--clean-all] [-l|--list] [--] args" | wrap "Usage ${0##*/} " 478*8975f5c5SAndroid Build Coastguard Worker echo " help: print this message" | wrap " " 479*8975f5c5SAndroid Build Coastguard Worker echo " list: list all known chroot environments" | wrap " " 480*8975f5c5SAndroid Build Coastguard Worker echo " clean: remove all old chroot sessions for \"${chroot}\"" | wrap " " 481*8975f5c5SAndroid Build Coastguard Worker echo " clean-all: remove all old chroot sessions for all environments" | wrap " " 482*8975f5c5SAndroid Build Coastguard Worker exit 0 483*8975f5c5SAndroid Build Coastguard Worker} 484*8975f5c5SAndroid Build Coastguard Worker 485*8975f5c5SAndroid Build Coastguard Workerclean() { 486*8975f5c5SAndroid Build Coastguard Worker local s t rc 487*8975f5c5SAndroid Build Coastguard Worker rc=0 488*8975f5c5SAndroid Build Coastguard Worker for s in $(schroot -l --all-sessions); do 489*8975f5c5SAndroid Build Coastguard Worker if [ -n "$1" ]; then 490*8975f5c5SAndroid Build Coastguard Worker t="${s#session:}" 491*8975f5c5SAndroid Build Coastguard Worker [ "${t#${chroot}-}" == "${t}" ] && continue 492*8975f5c5SAndroid Build Coastguard Worker fi 493*8975f5c5SAndroid Build Coastguard Worker if ls -l /proc/*/{cwd,fd} 2>/dev/null | 494*8975f5c5SAndroid Build Coastguard Worker fgrep -qs "/var/lib/schroot/mount/${t}"; then 495*8975f5c5SAndroid Build Coastguard Worker echo "Session \"${t}\" still has active users, not cleaning up" | wrap 496*8975f5c5SAndroid Build Coastguard Worker rc=1 497*8975f5c5SAndroid Build Coastguard Worker continue 498*8975f5c5SAndroid Build Coastguard Worker fi 499*8975f5c5SAndroid Build Coastguard Worker sudo schroot -c "${s}" -e || rc=1 500*8975f5c5SAndroid Build Coastguard Worker done 501*8975f5c5SAndroid Build Coastguard Worker exit ${rc} 502*8975f5c5SAndroid Build Coastguard Worker} 503*8975f5c5SAndroid Build Coastguard Worker 504*8975f5c5SAndroid Build Coastguard Workerlist() { 505*8975f5c5SAndroid Build Coastguard Worker for e in $(schroot -l); do 506*8975f5c5SAndroid Build Coastguard Worker e="${e#chroot:}" 507*8975f5c5SAndroid Build Coastguard Worker [ -x "/usr/local/bin/${e}" ] || continue 508*8975f5c5SAndroid Build Coastguard Worker if schroot -l --all-sessions 2>/dev/null | 509*8975f5c5SAndroid Build Coastguard Worker sed 's/^session://' | 510*8975f5c5SAndroid Build Coastguard Worker grep -qs "^${e}-"; then 511*8975f5c5SAndroid Build Coastguard Worker echo "${e} is currently active" 512*8975f5c5SAndroid Build Coastguard Worker else 513*8975f5c5SAndroid Build Coastguard Worker echo "${e}" 514*8975f5c5SAndroid Build Coastguard Worker fi 515*8975f5c5SAndroid Build Coastguard Worker done 516*8975f5c5SAndroid Build Coastguard Worker exit 0 517*8975f5c5SAndroid Build Coastguard Worker} 518*8975f5c5SAndroid Build Coastguard Worker 519*8975f5c5SAndroid Build Coastguard Workerwhile [ "$#" -ne 0 ]; do 520*8975f5c5SAndroid Build Coastguard Worker case "$1" in 521*8975f5c5SAndroid Build Coastguard Worker --) shift; break;; 522*8975f5c5SAndroid Build Coastguard Worker -h|--help) shift; help;; 523*8975f5c5SAndroid Build Coastguard Worker -l|--list) shift; list;; 524*8975f5c5SAndroid Build Coastguard Worker -c|--clean) shift; clean "${chroot}";; 525*8975f5c5SAndroid Build Coastguard Worker -C|--clean-all) shift; clean;; 526*8975f5c5SAndroid Build Coastguard Worker *) break;; 527*8975f5c5SAndroid Build Coastguard Worker esac 528*8975f5c5SAndroid Build Coastguard Workerdone 529*8975f5c5SAndroid Build Coastguard Worker 530*8975f5c5SAndroid Build Coastguard Worker# Start a new chroot session and keep track of the session id. We inject this 531*8975f5c5SAndroid Build Coastguard Worker# id into all processes that run inside the chroot. Unless they go out of their 532*8975f5c5SAndroid Build Coastguard Worker# way to clear their environment, we can then later identify our child and 533*8975f5c5SAndroid Build Coastguard Worker# grand-child processes by scanning their environment. 534*8975f5c5SAndroid Build Coastguard Workersession="$(schroot -c "${chroot}" -b)" 535*8975f5c5SAndroid Build Coastguard Workerexport CHROOT_SESSION_ID="${session}" 536*8975f5c5SAndroid Build Coastguard Worker 537*8975f5c5SAndroid Build Coastguard Workerif [ $# -eq 0 ]; then 538*8975f5c5SAndroid Build Coastguard Worker # Run an interactive shell session 539*8975f5c5SAndroid Build Coastguard Worker schroot -c "${session}" -r -p 540*8975f5c5SAndroid Build Coastguard Workerelse 541*8975f5c5SAndroid Build Coastguard Worker # Run a command inside of the chroot environment 542*8975f5c5SAndroid Build Coastguard Worker p="$1"; shift 543*8975f5c5SAndroid Build Coastguard Worker schroot -c "${session}" -r -p "$p" -- "$@" 544*8975f5c5SAndroid Build Coastguard Workerfi 545*8975f5c5SAndroid Build Coastguard Workerrc=$? 546*8975f5c5SAndroid Build Coastguard Worker 547*8975f5c5SAndroid Build Coastguard Worker# Compute the inode of the root directory inside of the chroot environment. 548*8975f5c5SAndroid Build Coastguard Workeri=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. | 549*8975f5c5SAndroid Build Coastguard Worker awk '{ print $1 }') 2>/dev/null 550*8975f5c5SAndroid Build Coastguard Workerother_pids= 551*8975f5c5SAndroid Build Coastguard Workerwhile [ -n "$i" ]; do 552*8975f5c5SAndroid Build Coastguard Worker # Identify processes by the inode number of their root directory. Then 553*8975f5c5SAndroid Build Coastguard Worker # remove all processes that we know belong to other sessions. We use 554*8975f5c5SAndroid Build Coastguard Worker # "sort | uniq -u" to do what amounts to a "set subtraction operation". 555*8975f5c5SAndroid Build Coastguard Worker pids=$({ ls -id1 /proc/*/root/. 2>/dev/null | 556*8975f5c5SAndroid Build Coastguard Worker sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1, 557*8975f5c5SAndroid Build Coastguard Worker t 558*8975f5c5SAndroid Build Coastguard Worker d'; 559*8975f5c5SAndroid Build Coastguard Worker echo "${other_pids}"; 560*8975f5c5SAndroid Build Coastguard Worker echo "${other_pids}"; } | sort | uniq -u) >/dev/null 2>&1 561*8975f5c5SAndroid Build Coastguard Worker # Kill all processes that are still left running in the session. This is 562*8975f5c5SAndroid Build Coastguard Worker # typically an assortment of daemon processes that were started 563*8975f5c5SAndroid Build Coastguard Worker # automatically. They result in us being unable to tear down the session 564*8975f5c5SAndroid Build Coastguard Worker # cleanly. 565*8975f5c5SAndroid Build Coastguard Worker [ -z "${pids}" ] && break 566*8975f5c5SAndroid Build Coastguard Worker for j in $pids; do 567*8975f5c5SAndroid Build Coastguard Worker # Unfortunately, the way that schroot sets up sessions has the 568*8975f5c5SAndroid Build Coastguard Worker # side-effect of being unable to tell one session apart from another. 569*8975f5c5SAndroid Build Coastguard Worker # This can result in us attempting to kill processes in other sessions. 570*8975f5c5SAndroid Build Coastguard Worker # We make a best-effort to avoid doing so. 571*8975f5c5SAndroid Build Coastguard Worker k="$( ( xargs -0 -n1 </proc/$j/environ ) 2>/dev/null | 572*8975f5c5SAndroid Build Coastguard Worker sed 's/^CHROOT_SESSION_ID=/x/;t1;d;:1;q')" 573*8975f5c5SAndroid Build Coastguard Worker if [ -n "${k}" -a "${k#x}" != "${session}" ]; then 574*8975f5c5SAndroid Build Coastguard Worker other_pids="${other_pids} 575*8975f5c5SAndroid Build Coastguard Worker${j}" 576*8975f5c5SAndroid Build Coastguard Worker continue 577*8975f5c5SAndroid Build Coastguard Worker fi 578*8975f5c5SAndroid Build Coastguard Worker kill -9 $pids 579*8975f5c5SAndroid Build Coastguard Worker done 580*8975f5c5SAndroid Build Coastguard Workerdone 581*8975f5c5SAndroid Build Coastguard Worker# End the chroot session. This should clean up all temporary files. But if we 582*8975f5c5SAndroid Build Coastguard Worker# earlier failed to terminate all (daemon) processes inside of the session, 583*8975f5c5SAndroid Build Coastguard Worker# deleting the session could fail. When that happens, the user has to manually 584*8975f5c5SAndroid Build Coastguard Worker# clean up the stale files by invoking us with "--clean" after having killed 585*8975f5c5SAndroid Build Coastguard Worker# all running processes. 586*8975f5c5SAndroid Build Coastguard Workerschroot -c "${session}" -e 587*8975f5c5SAndroid Build Coastguard Workerexit $rc 588*8975f5c5SAndroid Build Coastguard WorkerEOF 589*8975f5c5SAndroid Build Coastguard Workersudo chown root:root /usr/local/bin/"${target%bit}" 590*8975f5c5SAndroid Build Coastguard Workersudo chmod 755 /usr/local/bin/"${target%bit}" 591*8975f5c5SAndroid Build Coastguard Worker 592*8975f5c5SAndroid Build Coastguard Worker# Add the standard Ubuntu update repositories if requested. 593*8975f5c5SAndroid Build Coastguard Worker[ "${alt_repos}" = "y" -a \ 594*8975f5c5SAndroid Build Coastguard Worker -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && 595*8975f5c5SAndroid Build Coastguard Workersudo sed -i '/^deb .* [^ -]\+ main$/p 596*8975f5c5SAndroid Build Coastguard Worker s/^\(deb .* [^ -]\+\) main/\1-security main/ 597*8975f5c5SAndroid Build Coastguard Worker p 598*8975f5c5SAndroid Build Coastguard Worker t1 599*8975f5c5SAndroid Build Coastguard Worker d 600*8975f5c5SAndroid Build Coastguard Worker :1;s/-security main/-updates main/ 601*8975f5c5SAndroid Build Coastguard Worker t 602*8975f5c5SAndroid Build Coastguard Worker d' "/var/lib/chroot/${target}/etc/apt/sources.list" 603*8975f5c5SAndroid Build Coastguard Worker 604*8975f5c5SAndroid Build Coastguard Worker# Add a few more repositories to the chroot 605*8975f5c5SAndroid Build Coastguard Worker[ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && 606*8975f5c5SAndroid Build Coastguard Workersudo sed -i 's/ main$/ main restricted universe multiverse/' \ 607*8975f5c5SAndroid Build Coastguard Worker "/var/lib/chroot/${target}/etc/apt/sources.list" 608*8975f5c5SAndroid Build Coastguard Worker 609*8975f5c5SAndroid Build Coastguard Worker# Add the Ubuntu "partner" repository, if available 610*8975f5c5SAndroid Build Coastguard Workerif [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && 611*8975f5c5SAndroid Build Coastguard Worker HEAD "http://archive.canonical.com/ubuntu/dists/${distname}/partner" \ 612*8975f5c5SAndroid Build Coastguard Worker >&/dev/null; then 613*8975f5c5SAndroid Build Coastguard Worker sudo sh -c ' 614*8975f5c5SAndroid Build Coastguard Worker echo "deb http://archive.canonical.com/ubuntu" \ 615*8975f5c5SAndroid Build Coastguard Worker "'"${distname}"' partner" \ 616*8975f5c5SAndroid Build Coastguard Worker >>"/var/lib/chroot/'"${target}"'/etc/apt/sources.list"' 617*8975f5c5SAndroid Build Coastguard Workerfi 618*8975f5c5SAndroid Build Coastguard Worker 619*8975f5c5SAndroid Build Coastguard Worker# Add source repositories, if the user requested we do so 620*8975f5c5SAndroid Build Coastguard Worker[ "${add_srcs}" = "y" -a \ 621*8975f5c5SAndroid Build Coastguard Worker -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && 622*8975f5c5SAndroid Build Coastguard Workersudo sed -i '/^deb[^-]/p 623*8975f5c5SAndroid Build Coastguard Worker s/^deb\([^-]\)/deb-src\1/' \ 624*8975f5c5SAndroid Build Coastguard Worker "/var/lib/chroot/${target}/etc/apt/sources.list" 625*8975f5c5SAndroid Build Coastguard Worker 626*8975f5c5SAndroid Build Coastguard Worker# Set apt proxy if host has set http_proxy 627*8975f5c5SAndroid Build Coastguard Workerif [ -n "${http_proxy}" ]; then 628*8975f5c5SAndroid Build Coastguard Worker sudo sh -c ' 629*8975f5c5SAndroid Build Coastguard Worker echo "Acquire::http::proxy \"'"${http_proxy}"'\";" \ 630*8975f5c5SAndroid Build Coastguard Worker >>"/var/lib/chroot/'"${target}"'/etc/apt/apt.conf"' 631*8975f5c5SAndroid Build Coastguard Workerfi 632*8975f5c5SAndroid Build Coastguard Worker 633*8975f5c5SAndroid Build Coastguard Worker# Update packages 634*8975f5c5SAndroid Build Coastguard Workersudo "/usr/local/bin/${target%bit}" /bin/sh -c ' 635*8975f5c5SAndroid Build Coastguard Worker apt-get update; apt-get -y dist-upgrade' || : 636*8975f5c5SAndroid Build Coastguard Worker 637*8975f5c5SAndroid Build Coastguard Worker# Install a couple of missing packages 638*8975f5c5SAndroid Build Coastguard Workerfor i in debian-keyring ubuntu-keyring locales sudo; do 639*8975f5c5SAndroid Build Coastguard Worker [ -d "/var/lib/chroot/${target}/usr/share/doc/$i" ] || 640*8975f5c5SAndroid Build Coastguard Worker sudo "/usr/local/bin/${target%bit}" apt-get -y install "$i" || : 641*8975f5c5SAndroid Build Coastguard Workerdone 642*8975f5c5SAndroid Build Coastguard Worker 643*8975f5c5SAndroid Build Coastguard Worker# Configure locales 644*8975f5c5SAndroid Build Coastguard Workersudo "/usr/local/bin/${target%bit}" /bin/sh -c ' 645*8975f5c5SAndroid Build Coastguard Worker l='"${LANG:-en_US}"'; l="${l%%.*}" 646*8975f5c5SAndroid Build Coastguard Worker [ -r /etc/locale.gen ] && 647*8975f5c5SAndroid Build Coastguard Worker sed -i "s/^# \($l\)/\1/" /etc/locale.gen 648*8975f5c5SAndroid Build Coastguard Worker locale-gen $LANG en_US en_US.UTF-8' || : 649*8975f5c5SAndroid Build Coastguard Worker 650*8975f5c5SAndroid Build Coastguard Worker# Enable multi-arch support, if available 651*8975f5c5SAndroid Build Coastguard Workersudo "/usr/local/bin/${target%bit}" dpkg --assert-multi-arch >&/dev/null && 652*8975f5c5SAndroid Build Coastguard Worker [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && { 653*8975f5c5SAndroid Build Coastguard Worker sudo sed -i 's/ / [arch=amd64,i386] /' \ 654*8975f5c5SAndroid Build Coastguard Worker "/var/lib/chroot/${target}/etc/apt/sources.list" 655*8975f5c5SAndroid Build Coastguard Worker [ -d /var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/ ] && 656*8975f5c5SAndroid Build Coastguard Worker sudo "/usr/local/bin/${target%bit}" dpkg --add-architecture \ 657*8975f5c5SAndroid Build Coastguard Worker $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) >&/dev/null || 658*8975f5c5SAndroid Build Coastguard Worker echo foreign-architecture \ 659*8975f5c5SAndroid Build Coastguard Worker $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) | 660*8975f5c5SAndroid Build Coastguard Worker sudo sh -c \ 661*8975f5c5SAndroid Build Coastguard Worker "cat >'/var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/multiarch'" 662*8975f5c5SAndroid Build Coastguard Worker} 663*8975f5c5SAndroid Build Coastguard Worker 664*8975f5c5SAndroid Build Coastguard Worker# Configure "sudo" package 665*8975f5c5SAndroid Build Coastguard Workersudo "/usr/local/bin/${target%bit}" /bin/sh -c ' 666*8975f5c5SAndroid Build Coastguard Worker egrep -qs '"'^$(id -nu) '"' /etc/sudoers || 667*8975f5c5SAndroid Build Coastguard Worker echo '"'$(id -nu) ALL=(ALL) ALL'"' >>/etc/sudoers' 668*8975f5c5SAndroid Build Coastguard Worker 669*8975f5c5SAndroid Build Coastguard Worker# Install a few more commonly used packages 670*8975f5c5SAndroid Build Coastguard Workersudo "/usr/local/bin/${target%bit}" apt-get -y install \ 671*8975f5c5SAndroid Build Coastguard Worker autoconf automake1.9 dpkg-dev g++-multilib gcc-multilib gdb less libtool \ 672*8975f5c5SAndroid Build Coastguard Worker lsof strace 673*8975f5c5SAndroid Build Coastguard Worker 674*8975f5c5SAndroid Build Coastguard Worker# If running a 32bit environment on a 64bit machine, install a few binaries 675*8975f5c5SAndroid Build Coastguard Worker# as 64bit. This is only done automatically if the chroot distro is the same as 676*8975f5c5SAndroid Build Coastguard Worker# the host, otherwise there might be incompatibilities in build settings or 677*8975f5c5SAndroid Build Coastguard Worker# runtime dependencies. The user can force it with the '-c' flag. 678*8975f5c5SAndroid Build Coastguard Workerhost_distro=$(grep -s DISTRIB_CODENAME /etc/lsb-release | \ 679*8975f5c5SAndroid Build Coastguard Worker cut -d "=" -f 2) 680*8975f5c5SAndroid Build Coastguard Workerif [ "${copy_64}" = "y" -o \ 681*8975f5c5SAndroid Build Coastguard Worker "${host_distro}" = "${distname}" -a "${arch}" = 32bit ] && \ 682*8975f5c5SAndroid Build Coastguard Worker file /bin/bash 2>/dev/null | grep -q x86-64; then 683*8975f5c5SAndroid Build Coastguard Worker readlinepkg=$(sudo "/usr/local/bin/${target%bit}" sh -c \ 684*8975f5c5SAndroid Build Coastguard Worker 'apt-cache search "lib64readline.\$" | sort | tail -n 1 | cut -d " " -f 1') 685*8975f5c5SAndroid Build Coastguard Worker sudo "/usr/local/bin/${target%bit}" apt-get -y install \ 686*8975f5c5SAndroid Build Coastguard Worker lib64expat1 lib64ncurses5 ${readlinepkg} lib64z1 lib64stdc++6 687*8975f5c5SAndroid Build Coastguard Worker dep= 688*8975f5c5SAndroid Build Coastguard Worker for i in binutils gdb; do 689*8975f5c5SAndroid Build Coastguard Worker [ -d /usr/share/doc/"$i" ] || dep="$dep $i" 690*8975f5c5SAndroid Build Coastguard Worker done 691*8975f5c5SAndroid Build Coastguard Worker [ -n "$dep" ] && sudo apt-get -y install $dep 692*8975f5c5SAndroid Build Coastguard Worker sudo mkdir -p "/var/lib/chroot/${target}/usr/local/lib/amd64" 693*8975f5c5SAndroid Build Coastguard Worker for i in libbfd libpython; do 694*8975f5c5SAndroid Build Coastguard Worker lib="$({ ldd /usr/bin/ld; ldd /usr/bin/gdb; } | 695*8975f5c5SAndroid Build Coastguard Worker grep -s "$i" | awk '{ print $3 }')" 696*8975f5c5SAndroid Build Coastguard Worker if [ -n "$lib" -a -r "$lib" ]; then 697*8975f5c5SAndroid Build Coastguard Worker sudo cp "$lib" "/var/lib/chroot/${target}/usr/local/lib/amd64" 698*8975f5c5SAndroid Build Coastguard Worker fi 699*8975f5c5SAndroid Build Coastguard Worker done 700*8975f5c5SAndroid Build Coastguard Worker for lib in libssl libcrypt; do 701*8975f5c5SAndroid Build Coastguard Worker for path in /usr/lib /usr/lib/x86_64-linux-gnu; do 702*8975f5c5SAndroid Build Coastguard Worker sudo cp $path/$lib* \ 703*8975f5c5SAndroid Build Coastguard Worker "/var/lib/chroot/${target}/usr/local/lib/amd64/" >&/dev/null || : 704*8975f5c5SAndroid Build Coastguard Worker done 705*8975f5c5SAndroid Build Coastguard Worker done 706*8975f5c5SAndroid Build Coastguard Worker for i in gdb ld; do 707*8975f5c5SAndroid Build Coastguard Worker sudo cp /usr/bin/$i "/var/lib/chroot/${target}/usr/local/lib/amd64/" 708*8975f5c5SAndroid Build Coastguard Worker sudo sh -c "cat >'/var/lib/chroot/${target}/usr/local/bin/$i'" <<EOF 709*8975f5c5SAndroid Build Coastguard Worker#!/bin/sh 710*8975f5c5SAndroid Build Coastguard Workerexec /lib64/ld-linux-x86-64.so.2 --library-path /usr/local/lib/amd64 \ 711*8975f5c5SAndroid Build Coastguard Worker /usr/local/lib/amd64/$i "\$@" 712*8975f5c5SAndroid Build Coastguard WorkerEOF 713*8975f5c5SAndroid Build Coastguard Worker sudo chmod 755 "/var/lib/chroot/${target}/usr/local/bin/$i" 714*8975f5c5SAndroid Build Coastguard Worker done 715*8975f5c5SAndroid Build Coastguard Workerfi 716*8975f5c5SAndroid Build Coastguard Worker 717*8975f5c5SAndroid Build Coastguard Worker 718*8975f5c5SAndroid Build Coastguard Worker# If the install-build-deps.sh script can be found, offer to run it now 719*8975f5c5SAndroid Build Coastguard Workerscript="$(dirname $(readlink -f "$0"))/install-build-deps.sh" 720*8975f5c5SAndroid Build Coastguard Workerif [ -x "${script}" ]; then 721*8975f5c5SAndroid Build Coastguard Worker while :; do 722*8975f5c5SAndroid Build Coastguard Worker echo 723*8975f5c5SAndroid Build Coastguard Worker echo "If you plan on building Chrome inside of the new chroot environment," 724*8975f5c5SAndroid Build Coastguard Worker echo "you now have to install the build dependencies. Do you want me to" 725*8975f5c5SAndroid Build Coastguard Worker printf "start the script that does this for you (y/n)? " 726*8975f5c5SAndroid Build Coastguard Worker read install_deps 727*8975f5c5SAndroid Build Coastguard Worker case "${install_deps}" in 728*8975f5c5SAndroid Build Coastguard Worker y|Y) 729*8975f5c5SAndroid Build Coastguard Worker echo 730*8975f5c5SAndroid Build Coastguard Worker # We prefer running the script in-place, but this might not be 731*8975f5c5SAndroid Build Coastguard Worker # possible, if it lives on a network filesystem that denies 732*8975f5c5SAndroid Build Coastguard Worker # access to root. 733*8975f5c5SAndroid Build Coastguard Worker tmp_script= 734*8975f5c5SAndroid Build Coastguard Worker if ! sudo /usr/local/bin/"${target%bit}" \ 735*8975f5c5SAndroid Build Coastguard Worker sh -c "[ -x '${script}' ]" >&/dev/null; then 736*8975f5c5SAndroid Build Coastguard Worker tmp_script="/tmp/${script##*/}" 737*8975f5c5SAndroid Build Coastguard Worker cp "${script}" "${tmp_script}" 738*8975f5c5SAndroid Build Coastguard Worker fi 739*8975f5c5SAndroid Build Coastguard Worker # Some distributions automatically start an instance of the system- 740*8975f5c5SAndroid Build Coastguard Worker # wide dbus daemon, cron daemon or of the logging daemon, when 741*8975f5c5SAndroid Build Coastguard Worker # installing the Chrome build depencies. This prevents the chroot 742*8975f5c5SAndroid Build Coastguard Worker # session from being closed. So, we always try to shut down any running 743*8975f5c5SAndroid Build Coastguard Worker # instance of dbus and rsyslog. 744*8975f5c5SAndroid Build Coastguard Worker sudo /usr/local/bin/"${target%bit}" sh -c "${script}; 745*8975f5c5SAndroid Build Coastguard Worker rc=$?; 746*8975f5c5SAndroid Build Coastguard Worker /etc/init.d/cron stop >/dev/null 2>&1 || :; 747*8975f5c5SAndroid Build Coastguard Worker /etc/init.d/rsyslog stop >/dev/null 2>&1 || :; 748*8975f5c5SAndroid Build Coastguard Worker /etc/init.d/dbus stop >/dev/null 2>&1 || :; 749*8975f5c5SAndroid Build Coastguard Worker exit $rc" 750*8975f5c5SAndroid Build Coastguard Worker rc=$? 751*8975f5c5SAndroid Build Coastguard Worker [ -n "${tmp_script}" ] && rm -f "${tmp_script}" 752*8975f5c5SAndroid Build Coastguard Worker [ $rc -ne 0 ] && exit $rc 753*8975f5c5SAndroid Build Coastguard Worker break 754*8975f5c5SAndroid Build Coastguard Worker ;; 755*8975f5c5SAndroid Build Coastguard Worker n|N) 756*8975f5c5SAndroid Build Coastguard Worker break 757*8975f5c5SAndroid Build Coastguard Worker ;; 758*8975f5c5SAndroid Build Coastguard Worker esac 759*8975f5c5SAndroid Build Coastguard Worker done 760*8975f5c5SAndroid Build Coastguard Worker echo 761*8975f5c5SAndroid Build Coastguard Workerfi 762*8975f5c5SAndroid Build Coastguard Worker 763*8975f5c5SAndroid Build Coastguard Worker# Check whether ~/chroot is on a (slow) network file system and offer to 764*8975f5c5SAndroid Build Coastguard Worker# relocate it. Also offer relocation, if the user appears to have multiple 765*8975f5c5SAndroid Build Coastguard Worker# spindles (as indicated by "${bind_mount}" being non-empty). 766*8975f5c5SAndroid Build Coastguard Worker# We only offer this option, if it doesn't look as if a chroot environment 767*8975f5c5SAndroid Build Coastguard Worker# is currently active. Otherwise, relocation is unlikely to work and it 768*8975f5c5SAndroid Build Coastguard Worker# can be difficult for the user to recover from the failed attempt to relocate 769*8975f5c5SAndroid Build Coastguard Worker# the ~/chroot directory. 770*8975f5c5SAndroid Build Coastguard Worker# We don't aim to solve this problem for every configuration, 771*8975f5c5SAndroid Build Coastguard Worker# but try to help with the common cases. For more advanced configuration 772*8975f5c5SAndroid Build Coastguard Worker# options, the user can always manually adjust things. 773*8975f5c5SAndroid Build Coastguard Workermkdir -p "${HOME}/chroot/" 774*8975f5c5SAndroid Build Coastguard Workerif [ ! -h "${HOME}/chroot" ] && 775*8975f5c5SAndroid Build Coastguard Worker ! egrep -qs '^[^[:space:]]*/chroot' /etc/fstab && 776*8975f5c5SAndroid Build Coastguard Worker { [ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] || 777*8975f5c5SAndroid Build Coastguard Worker is_network_drive "${HOME}/chroot"; } && 778*8975f5c5SAndroid Build Coastguard Worker ! egrep -qs '/var/lib/[^/]*chroot/.*/chroot' /proc/mounts; then 779*8975f5c5SAndroid Build Coastguard Worker echo "${HOME}/chroot is currently located on the same device as your" 780*8975f5c5SAndroid Build Coastguard Worker echo "home directory." 781*8975f5c5SAndroid Build Coastguard Worker echo "This might not be what you want. Do you want me to move it somewhere" 782*8975f5c5SAndroid Build Coastguard Worker echo "else?" 783*8975f5c5SAndroid Build Coastguard Worker # If the computer has multiple spindles, many users configure all or part of 784*8975f5c5SAndroid Build Coastguard Worker # the secondary hard disk to be writable by the primary user of this machine. 785*8975f5c5SAndroid Build Coastguard Worker # Make some reasonable effort to detect this type of configuration and 786*8975f5c5SAndroid Build Coastguard Worker # then offer a good location for where to put the ~/chroot directory. 787*8975f5c5SAndroid Build Coastguard Worker suggest= 788*8975f5c5SAndroid Build Coastguard Worker for i in $(echo "${bind_mounts}"|cut -d ' ' -f 1); do 789*8975f5c5SAndroid Build Coastguard Worker if [ -d "$i" -a -w "$i" -a \( ! -a "$i/chroot" -o -w "$i/chroot/." \) ] && 790*8975f5c5SAndroid Build Coastguard Worker ! is_network_drive "$i"; then 791*8975f5c5SAndroid Build Coastguard Worker suggest="$i" 792*8975f5c5SAndroid Build Coastguard Worker else 793*8975f5c5SAndroid Build Coastguard Worker for j in "$i/"*; do 794*8975f5c5SAndroid Build Coastguard Worker if [ -d "$j" -a -w "$j" -a \ 795*8975f5c5SAndroid Build Coastguard Worker \( ! -a "$j/chroot" -o -w "$j/chroot/." \) ] && 796*8975f5c5SAndroid Build Coastguard Worker ! is_network_drive "$j"; then 797*8975f5c5SAndroid Build Coastguard Worker suggest="$j" 798*8975f5c5SAndroid Build Coastguard Worker else 799*8975f5c5SAndroid Build Coastguard Worker for k in "$j/"*; do 800*8975f5c5SAndroid Build Coastguard Worker if [ -d "$k" -a -w "$k" -a \ 801*8975f5c5SAndroid Build Coastguard Worker \( ! -a "$k/chroot" -o -w "$k/chroot/." \) ] && 802*8975f5c5SAndroid Build Coastguard Worker ! is_network_drive "$k"; then 803*8975f5c5SAndroid Build Coastguard Worker suggest="$k" 804*8975f5c5SAndroid Build Coastguard Worker break 805*8975f5c5SAndroid Build Coastguard Worker fi 806*8975f5c5SAndroid Build Coastguard Worker done 807*8975f5c5SAndroid Build Coastguard Worker fi 808*8975f5c5SAndroid Build Coastguard Worker [ -n "${suggest}" ] && break 809*8975f5c5SAndroid Build Coastguard Worker done 810*8975f5c5SAndroid Build Coastguard Worker fi 811*8975f5c5SAndroid Build Coastguard Worker [ -n "${suggest}" ] && break 812*8975f5c5SAndroid Build Coastguard Worker done 813*8975f5c5SAndroid Build Coastguard Worker def_suggest="${HOME}" 814*8975f5c5SAndroid Build Coastguard Worker if [ -n "${suggest}" ]; then 815*8975f5c5SAndroid Build Coastguard Worker # For home directories that reside on network drives, make our suggestion 816*8975f5c5SAndroid Build Coastguard Worker # the default option. For home directories that reside on a local drive, 817*8975f5c5SAndroid Build Coastguard Worker # require that the user manually enters the new location. 818*8975f5c5SAndroid Build Coastguard Worker if is_network_drive "${HOME}"; then 819*8975f5c5SAndroid Build Coastguard Worker def_suggest="${suggest}" 820*8975f5c5SAndroid Build Coastguard Worker else 821*8975f5c5SAndroid Build Coastguard Worker echo "A good location would probably be in \"${suggest}\"" 822*8975f5c5SAndroid Build Coastguard Worker fi 823*8975f5c5SAndroid Build Coastguard Worker fi 824*8975f5c5SAndroid Build Coastguard Worker while :; do 825*8975f5c5SAndroid Build Coastguard Worker printf "Physical location [${def_suggest}]: " 826*8975f5c5SAndroid Build Coastguard Worker read dir 827*8975f5c5SAndroid Build Coastguard Worker [ -z "${dir}" ] && dir="${def_suggest}" 828*8975f5c5SAndroid Build Coastguard Worker [ "${dir%%/}" == "${HOME%%/}" ] && break 829*8975f5c5SAndroid Build Coastguard Worker if ! [ -d "${dir}" -a -w "${dir}" ] || 830*8975f5c5SAndroid Build Coastguard Worker [ -a "${dir}/chroot" -a ! -w "${dir}/chroot/." ]; then 831*8975f5c5SAndroid Build Coastguard Worker echo "Cannot write to ${dir}/chroot. Please try again" 832*8975f5c5SAndroid Build Coastguard Worker else 833*8975f5c5SAndroid Build Coastguard Worker mv "${HOME}/chroot" "${dir}/chroot" 834*8975f5c5SAndroid Build Coastguard Worker ln -s "${dir}/chroot" "${HOME}/chroot" 835*8975f5c5SAndroid Build Coastguard Worker for i in $(list_all_chroots); do 836*8975f5c5SAndroid Build Coastguard Worker sudo "$i" mkdir -p "${dir}/chroot" 837*8975f5c5SAndroid Build Coastguard Worker done 838*8975f5c5SAndroid Build Coastguard Worker sudo sed -i "s,${HOME}/chroot,${dir}/chroot,g" /etc/schroot/mount-* 839*8975f5c5SAndroid Build Coastguard Worker break 840*8975f5c5SAndroid Build Coastguard Worker fi 841*8975f5c5SAndroid Build Coastguard Worker done 842*8975f5c5SAndroid Build Coastguard Workerfi 843*8975f5c5SAndroid Build Coastguard Worker 844*8975f5c5SAndroid Build Coastguard Worker# Clean up package files 845*8975f5c5SAndroid Build Coastguard Workersudo schroot -c "${target%bit}" -p -- apt-get clean 846*8975f5c5SAndroid Build Coastguard Workersudo apt-get clean 847*8975f5c5SAndroid Build Coastguard Worker 848*8975f5c5SAndroid Build Coastguard Workertrap '' INT TERM QUIT HUP 849*8975f5c5SAndroid Build Coastguard Workertrap '' EXIT 850*8975f5c5SAndroid Build Coastguard Worker 851*8975f5c5SAndroid Build Coastguard Worker# Let the user know what we did 852*8975f5c5SAndroid Build Coastguard Workercat <<EOF 853*8975f5c5SAndroid Build Coastguard Worker 854*8975f5c5SAndroid Build Coastguard Worker 855*8975f5c5SAndroid Build Coastguard WorkerSuccessfully installed ${distname} ${arch} 856*8975f5c5SAndroid Build Coastguard Worker 857*8975f5c5SAndroid Build Coastguard WorkerYou can run programs inside of the chroot by invoking the 858*8975f5c5SAndroid Build Coastguard Worker"/usr/local/bin/${target%bit}" command. 859*8975f5c5SAndroid Build Coastguard Worker 860*8975f5c5SAndroid Build Coastguard WorkerThis command can be used with arguments, in order to just run a single 861*8975f5c5SAndroid Build Coastguard Workerprogram inside of the chroot environment (e.g. "${target%bit} make chrome") 862*8975f5c5SAndroid Build Coastguard Workeror without arguments, in order to run an interactive shell session inside 863*8975f5c5SAndroid Build Coastguard Workerof the chroot environment. 864*8975f5c5SAndroid Build Coastguard Worker 865*8975f5c5SAndroid Build Coastguard WorkerIf you need to run things as "root", you can use "sudo" (e.g. try 866*8975f5c5SAndroid Build Coastguard Worker"sudo ${target%bit} apt-get update"). 867*8975f5c5SAndroid Build Coastguard Worker 868*8975f5c5SAndroid Build Coastguard WorkerYour home directory is shared between the host and the chroot. But I 869*8975f5c5SAndroid Build Coastguard Workerconfigured "${HOME}/chroot" to be private to the chroot environment. 870*8975f5c5SAndroid Build Coastguard WorkerYou can use it for files that need to differ between environments. This 871*8975f5c5SAndroid Build Coastguard Workerwould be a good place to store binaries that you have built from your 872*8975f5c5SAndroid Build Coastguard Workersource files. 873*8975f5c5SAndroid Build Coastguard Worker 874*8975f5c5SAndroid Build Coastguard WorkerFor Chrome, this probably means you want to make your "out" directory a 875*8975f5c5SAndroid Build Coastguard Workersymbolic link that points somewhere inside of "${HOME}/chroot". 876*8975f5c5SAndroid Build Coastguard Worker 877*8975f5c5SAndroid Build Coastguard WorkerYou still need to run "gclient runhooks" whenever you switch from building 878*8975f5c5SAndroid Build Coastguard Workeroutside of the chroot to inside of the chroot. But you will find that you 879*8975f5c5SAndroid Build Coastguard Workerdon't have to repeatedly erase and then completely rebuild all your object 880*8975f5c5SAndroid Build Coastguard Workerand binary files. 881*8975f5c5SAndroid Build Coastguard Worker 882*8975f5c5SAndroid Build Coastguard WorkerEOF 883