| OLD | NEW |
| (Empty) |
| 1 #!/bin/bash | |
| 2 | |
| 3 # Copyright (c) 2009 The Chromium OS 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. | |
| 6 | |
| 7 # This script sets up an Ubuntu chroot environment. The ideas come | |
| 8 # from https://wiki.ubuntu.com/DebootstrapChroot and conversations with | |
| 9 # tedbo. The script is passed the path to an empty folder, which will be | |
| 10 # populated with the files to form an Ubuntu Jaunty system with the packages | |
| 11 # listed in PACKAGE_LIST_FILE (below) and their dependencies. Once created, | |
| 12 # the password is set to PASSWORD (below). One can enter the chrooted | |
| 13 # environment for work by running | |
| 14 # enter_chroot_dev_environment.sh /path/to/chroot-root | |
| 15 | |
| 16 # Load common constants. This should be the first executable line. | |
| 17 # The path to common.sh should be relative to your script's location. | |
| 18 . "$(dirname "$0")/common.sh" | |
| 19 | |
| 20 # Script must be run outside the chroot and as a regular user. | |
| 21 assert_outside_chroot | |
| 22 assert_not_root_user | |
| 23 | |
| 24 DEFAULT_PKGLIST="$SRC_ROOT/package_repo/package-list-dev.txt" | |
| 25 | |
| 26 # Define command line flags | |
| 27 # See http://code.google.com/p/shflags/wiki/Documentation10x | |
| 28 DEFINE_string suite "$DEFAULT_DEV_SUITE" \ | |
| 29 "Ubuntu suite to use to create the development chroot." | |
| 30 DEFINE_string mirror "$DEFAULT_DEV_MIRROR" \ | |
| 31 "Ubuntu mirror to use to create the development chroot." | |
| 32 DEFINE_string mirror_src "$DEFAULT_DEV_MIRROR" \ | |
| 33 "Ubuntu mirror to use to apt-get package sources." | |
| 34 DEFINE_string chroot "$DEFAULT_CHROOT_DIR" \ | |
| 35 "Destination dir for the chroot environment." | |
| 36 DEFINE_string pkglist "$DEFAULT_PKGLIST" \ | |
| 37 "File listing additional packages to install." | |
| 38 DEFINE_boolean delete $FLAGS_FALSE "Delete an existing chroot." | |
| 39 DEFINE_boolean replace $FLAGS_FALSE "Overwrite existing chroot, if any." | |
| 40 | |
| 41 # Parse command line flags | |
| 42 FLAGS "$@" || exit 1 | |
| 43 eval set -- "${FLAGS_ARGV}" | |
| 44 | |
| 45 # Only now can we die on error. shflags functions leak non-zero error codes, | |
| 46 # so will die prematurely if 'set -e' is specified before now. | |
| 47 # TODO: replace shflags with something less error-prone, or contribute a fix. | |
| 48 set -e | |
| 49 | |
| 50 # Add additional components if file exists | |
| 51 OFFICIAL_COMPONENTS=$SRC_ROOT/package_repo/package-list-official.txt | |
| 52 [ -f $OFFICIAL_COMPONENTS ] || OFFICIAL_COMPONENTS= | |
| 53 COMPONENTS=$(cat $FLAGS_pkglist $OFFICIAL_COMPONENTS | sed -e 's/#.*//' | grep -
v '^ *$' | tr '\n' ' ') | |
| 54 FULLNAME="Chrome OS dev user" | |
| 55 DEFGROUPS="eng,admin,adm,dialout,cdrom,floppy,audio,dip,video" | |
| 56 PASSWORD=chronos | |
| 57 CRYPTED_PASSWD=$(perl -e 'print crypt($ARGV[0], "foo")', $PASSWORD) | |
| 58 | |
| 59 function in_chroot { | |
| 60 sudo chroot "$FLAGS_chroot" "$@" | |
| 61 } | |
| 62 | |
| 63 function bash_chroot { | |
| 64 # Use $* not $@ since 'bash -c' needs a single arg | |
| 65 sudo chroot "$FLAGS_chroot" bash -c "$*" | |
| 66 } | |
| 67 | |
| 68 function cleanup { | |
| 69 # Clean up mounts | |
| 70 mount | grep "on $(readlink -f "$FLAGS_chroot")" | awk '{print $3}' \ | |
| 71 | xargs -r -L1 sudo umount | |
| 72 } | |
| 73 | |
| 74 function delete_existing { | |
| 75 # Delete old chroot dir | |
| 76 if [ -e "$FLAGS_chroot" ] | |
| 77 then | |
| 78 echo "Cleaning up old mount points..." | |
| 79 cleanup | |
| 80 echo "Deleting $FLAGS_chroot..." | |
| 81 sudo rm -rf "$FLAGS_chroot" | |
| 82 fi | |
| 83 } | |
| 84 | |
| 85 # Install packages which may not be installed on the local system | |
| 86 install_if_missing debootstrap | |
| 87 | |
| 88 # Add debootstrap link for the suite, if it doesn't exist. | |
| 89 if [ ! -e "/usr/share/debootstrap/scripts/$FLAGS_suite" ] | |
| 90 then | |
| 91 sudo ln -s /usr/share/debootstrap/scripts/hardy \ | |
| 92 "/usr/share/debootstrap/scripts/$FLAGS_suite" | |
| 93 fi | |
| 94 | |
| 95 # Handle deleting an existing environment | |
| 96 if [ $FLAGS_delete -eq $FLAGS_TRUE ] | |
| 97 then | |
| 98 delete_existing | |
| 99 echo "Done." | |
| 100 exit 0 | |
| 101 fi | |
| 102 | |
| 103 # Handle existing directory | |
| 104 if [ -e "$FLAGS_chroot" ] | |
| 105 then | |
| 106 if [ $FLAGS_replace -eq $FLAGS_TRUE ] | |
| 107 then | |
| 108 delete_existing | |
| 109 else | |
| 110 echo "Directory $FLAGS_chroot already exists." | |
| 111 echo "Use --replace if you really want to overwrite it." | |
| 112 exit 1 | |
| 113 fi | |
| 114 fi | |
| 115 | |
| 116 # Create the destination directory | |
| 117 mkdir -p "$FLAGS_chroot" | |
| 118 | |
| 119 # Run debootstrap to create the base chroot environment | |
| 120 echo "Running debootstrap $FLAGS_mirror $FLAGS_suite ..." | |
| 121 echo "You may need to enter password for sudo now..." | |
| 122 sudo debootstrap --arch=i386 --exclude=rsyslog,ubuntu-minimal \ | |
| 123 "$FLAGS_suite" "$FLAGS_chroot" "$FLAGS_mirror" | |
| 124 echo "Done running debootstrap." | |
| 125 | |
| 126 # Set up necessary mounts | |
| 127 sudo mount none -t proc "$FLAGS_chroot/proc" | |
| 128 sudo mount none -t devpts "$FLAGS_chroot/dev/pts" | |
| 129 # ...and make sure we clean them up on exit | |
| 130 trap cleanup EXIT | |
| 131 | |
| 132 # Set up sudoers. Inside the chroot, the user can sudo without a password. | |
| 133 # (Safe enough, since the only way into the chroot is to 'sudo chroot', so | |
| 134 # the user's already typed in one sudo password...) | |
| 135 bash_chroot "echo %admin ALL=\(ALL\) ALL >> /etc/sudoers" | |
| 136 bash_chroot "echo $USER ALL=NOPASSWD: ALL >> /etc/sudoers" | |
| 137 | |
| 138 # Set up apt sources. | |
| 139 # prefer our tools or custom packages | |
| 140 bash_chroot "echo deb $DEFAULT_CHROMEOS_SERVER/tools chromiumos_dev \ | |
| 141 main > /etc/apt/sources.list" | |
| 142 # Add official apt source if file exists | |
| 143 OFFICIAL_SOURCE_LIST=$SRC_ROOT/package_repo/sources-official.list | |
| 144 if [ -f $OFFICIAL_SOURCE_LIST ] | |
| 145 then | |
| 146 # Copy the file into the chroot so it's cat'able | |
| 147 cp -fp $OFFICIAL_SOURCE_LIST $FLAGS_chroot/tmp | |
| 148 bash_chroot "cat /tmp/$(basename $OFFICIAL_SOURCE_LIST) >> /etc/apt/sources.li
st" | |
| 149 fi | |
| 150 # use specified mirror and suite for the rest of the development chroot | |
| 151 bash_chroot "echo deb $FLAGS_mirror $FLAGS_suite \ | |
| 152 main restricted multiverse universe >> /etc/apt/sources.list" | |
| 153 # NOTE: Add additional repos here, possibly via command-line args. | |
| 154 | |
| 155 # Enable sources for upstream packages. Currently, kernel source is checked in | |
| 156 # and all other sources are pulled via DEPS files. | |
| 157 bash_chroot "echo deb-src $FLAGS_mirror_src $FLAGS_suite \ | |
| 158 main restricted multiverse universe >> /etc/apt/sources.list" | |
| 159 | |
| 160 # Set /etc/debian_chroot so '(chroot)' shows up in shell prompts | |
| 161 CHROOT_BASE=`basename $FLAGS_chroot` | |
| 162 bash_chroot "echo $CHROOT_BASE > /etc/debian_chroot" | |
| 163 | |
| 164 # Copy config from outside chroot into chroot | |
| 165 sudo cp /etc/hosts "$FLAGS_chroot/etc/hosts" | |
| 166 | |
| 167 # Add ourselves as a user inside the chroot | |
| 168 in_chroot groupadd admin | |
| 169 in_chroot groupadd -g 5000 eng | |
| 170 in_chroot useradd -G ${DEFGROUPS} -g eng -u `id -u` -s \ | |
| 171 /bin/bash -m -c "${FULLNAME}" -p ${CRYPTED_PASSWD} ${USER} | |
| 172 | |
| 173 # Bind-mount trunk into chroot so we can install local packages | |
| 174 mkdir "${FLAGS_chroot}$CHROOT_TRUNK_DIR" | |
| 175 sudo mount --bind "$GCLIENT_ROOT" "${FLAGS_chroot}$CHROOT_TRUNK_DIR" | |
| 176 | |
| 177 # Niceties for interactive logins ('enter_chroot.sh'); these are ignored | |
| 178 # when specifying a command to enter_chroot.sh. | |
| 179 # Automatically change to scripts directory | |
| 180 echo "cd trunk/src/scripts" >> "$FLAGS_chroot/home/$USER/.profile" | |
| 181 | |
| 182 # Warn if attempting to use source control commands inside the chroot | |
| 183 for NOUSE in svn gcl gclient | |
| 184 do | |
| 185 echo "alias $NOUSE='echo In the chroot, it is a bad idea to run $NOUSE'" \ | |
| 186 >> "$FLAGS_chroot/home/$USER/.profile" | |
| 187 done | |
| 188 | |
| 189 if [ "$USER" = "chrome-bot" ] | |
| 190 then | |
| 191 # Copy ssh keys, so chroot'd chrome-bot can scp files from chrome-web. | |
| 192 cp -r ~/.ssh "$FLAGS_chroot/home/$USER/" | |
| 193 fi | |
| 194 | |
| 195 # Install additional packages | |
| 196 echo "Installing additional packages..." | |
| 197 in_chroot apt-get update | |
| 198 bash_chroot "export DEBIAN_FRONTEND=noninteractive LANG=C && \ | |
| 199 apt-get --yes --force-yes install $COMPONENTS" | |
| 200 | |
| 201 echo "Installing chromiumos-build tool..." | |
| 202 bash_chroot "cd $CHROOT_TRUNK_DIR/tools/chromiumos-build && \ | |
| 203 debuild -us -uc && \ | |
| 204 sudo dpkg -i ../chromiumos-build_*.deb && \ | |
| 205 rm ../chromiumos-build_*.{dsc,tar.gz,deb,build,changes}" | |
| 206 | |
| 207 | |
| 208 # Clean up the chroot mounts | |
| 209 trap - EXIT | |
| 210 cleanup | |
| 211 | |
| 212 if [ "$FLAGS_chroot" = "$DEFAULT_CHROOT_DIR" ] | |
| 213 then | |
| 214 CHROOT_EXAMPLE_OPT="" | |
| 215 else | |
| 216 CHROOT_EXAMPLE_OPT="--chroot=$FLAGS_chroot" | |
| 217 fi | |
| 218 | |
| 219 echo "All set up. To enter the chroot, run:" | |
| 220 echo " $SCRIPTS_DIR/enter_chroot.sh $CHROOT_EXAMPLE_OPT" | |
| 221 echo "" | |
| 222 echo "CAUTION: Do *NOT* rm -rf the chroot directory; if there are stale bind" | |
| 223 echo "mounts you may end up deleting your source tree too. To unmount and" | |
| 224 echo "delete the chroot cleanly, use:" | |
| 225 echo " $0 --delete $CHROOT_EXAMPLE_OPT" | |
| OLD | NEW |