media/webrtc/trunk/build/install-chroot.sh

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial