diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..2f2b2af95 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +crouton.tar.bz2 diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..1b73304bc --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +TARGET=crouton.tar.bz2 +SCRIPTS=enter-chroot.sh make-chroot.sh startxfce4.sh + + +$(TARGET): $(SCRIPTS) Makefile + tar --owner=root --group=root --mode=a=rx,u+w -cjf $(TARGET) $(SCRIPTS) diff --git a/enter-chroot.sh b/enter-chroot.sh new file mode 100755 index 000000000..15389b115 --- /dev/null +++ b/enter-chroot.sh @@ -0,0 +1,65 @@ +#!/bin/sh -e +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +if [ "$1" = -h -o "$1" = --help ]; then + echo "Usage: ${0##*/} [chroot-label [command [args...]]]" 1>&2 + echo " ${0##*/} chroot-label UID \"command [args...]\"" 1>&2 + exit 2 +fi + +CHROOT="/usr/local/${1:-precise}" +[ "$#" = 0 ] || shift + +if [ ! "$USER" = root -a ! "$UID" = 0 ]; then + echo "${0##*/} must be run as root." + exit 2 +fi + +cd "$CHROOT" + +# Did we specify a UID on the command line? +case "$1" in + ''|*[!0-9]*) cmd=;; + *) cmd='su - '"`awk -F: '$3=='"$1"'{print $1}' etc/passwd`" + shift + [ "$#" = 0 ] || cmd="$cmd -c";; +esac + +# Ensure the chroot is executable and writable +mp="$CHROOT" +while ! mountpoint -q "$mp"; do + mp="${mp%/*}" + [ -z "$mp" ] && mp=/ +done +mount -o remount,rw,dev,exec "$mp" +unset mp + +# Prepare chroot filesystem +# Soft-link resolv.conf so that updates are automatically propagated +mkdir -p etc/host-shill +ln -sf host-shill/resolv.conf etc/resolv.conf +# Mounts; will auto-unmount when the script exits +umount='umount etc/host-shill proc dev/pts sys tmp 2>/dev/null || { sleep 5; umount dev 2>/dev/null; } || true' +trap "$umount" 0 +mount --bind /var/run/shill etc/host-shill +mount --bind /proc proc +mount --bind /dev dev +mount --bind /sys sys +mount --bind /tmp tmp +mount -t devpts none dev/pts + +# Fix launching chrome/chromium +chmod 1777 dev/shm + +# Disable screen dimming (TODO: daemon script to poke it instead) +initctl stop powerd 2>/dev/null || nopowerd=1 + +# Start the chroot and any specified command +{ env -i TERM="$TERM" chroot . $cmd "$@"; ret=$?; } || true + +# Post-run; clean up +[ "$nopowerd" ] || initctl start powerd +eval "$umount" +exit $ret diff --git a/make-chroot.sh b/make-chroot.sh new file mode 100755 index 000000000..bdd370de1 --- /dev/null +++ b/make-chroot.sh @@ -0,0 +1,145 @@ +#!/bin/sh -e +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +if [ $# = 0 ]; then + echo "Usage: %{0##*/} user@hostname [release]" 1>&2 + echo "${0##*/} requires SSH access to a Debian-based system to boostrap." 1>&2 + exit 2 +fi +if [ ! "$USER" = root -a ! "$UID" = 0 ]; then + echo "${0##*/} must be run as root." 1>&2 + exit 2 +fi + +RELEASE="${2:-precise}" +MIRROR='http://archive.ubuntu.com/ubuntu/' + +ARCH="`uname -m | sed -e 's/x86_64/amd64/' -e 's/arm.*/arm/'`" + +CHROOT="$RELEASE" +if grep -q 'CHROMEOS' '/etc/lsb-release'; then + DESTDIR="/usr/local" +else + DESTDIR="chroot" +fi + +echo "Installing $RELEASE chroot to $DESTDIR/$CHROOT" 1>&2 +if [ ! -w "$DESTDIR" ]; then + echo "You do not have write access to $DESTDIR." 1>&2 + exit 2 +fi +mkdir -p "$DESTDIR" +oldpwd="$PWD" +cd "$DESTDIR" + +echo "Bootstrapping using ssh $1" 1>&2 + +tmp="`mktemp --tmpdir=/tmp make-chroot.XXX`" +trap "rm -f \"$tmp\"" INT HUP 0 + +while true; do +ssh $1 sh -ec \'' +if ! hash debootstrap; then + echo 'needsinstall' + exit +fi +tmp="`mktemp -d --tmpdir=/tmp make-chroot.XXX`" +trap "rm -rf \"$tmp\"" INT HUP 0 +cd "$tmp" +fakeroot debootstrap --foreign --arch="'"$ARCH"'" "'"$RELEASE"'" "'"$CHROOT"'" "'"$MIRROR"'" 1>&2 +echo -n "Compressing and downloading chroot environment..." 1>&2 +fakeroot tar --checkpoint=100 --checkpoint-action=exec="echo -n . 1>&2" -cajf- "'"$CHROOT"'" +'\' > "$tmp" + +if head -n 1 "$tmp" | grep -q needsinstall; then + echo 'debootstrap must be installed to prepare the chroot environment.' 1>&2 + ssh -t $1 sudo apt-get install debootstrap +else + break +fi +done + +echo 'done' 1>&2 +echo 'Unpacking chroot environment...' 1>&2 +tar -xf "$tmp" +rm -f "$tmp" +trap - INT HUP 0 + +echo 'Preparing chroot environment...' 1>&2 +echo -n 'Specify a new user: ' 1>&2 +read user junk +enterchroot="${0%/*}/enter-chroot.sh" +preparescript="$CHROOT/prepare-chroot.sh" +cat > "$preparescript" <> /etc/sudoers +fi + +echo 'Preparing software sources' 1>&2 +cat > /etc/apt/sources.list <&2 +apt-get -y upgrade + +echo 'Installing additional packages' 1>&2 +apt-get -y install wget openssh-client xorg gdebi chromium-browser +# Fix launching X11 from inside crosh +sed -i 's/allowed_users=.*/allowed_users=anybody/' '/etc/X11/Xwrapper.config' +# Ensure X always starts on display :1 +cat > /usr/local/bin/xinit <&2 +echo -n 'Would you like to install Xfce? [y/N] ' +read response junk +if [ "\$response" = y -o "\$response" = yes ]; then + apt-get -y install xfce4 xfce4-goodies shimmer-themes dictionaries-common- +fi + +echo 'Cleaning up' 1>&2 +apt-get clean +rm "\$0" +EOF +chmod +x "$preparescript" +cd "$oldpwd" +while ! "$enterchroot" "$CHROOT" "/${preparescript##*/}"; do + echo "Running /${preparescript##*/} inside the chroot failed." 1>&2 + echo "Will re-attempt in 5 seconds, or you can ctrl-C and run it yourself." 1>&2 + echo "This is the last step in setting up the chroot." 1>&2 + sleep 5 +done + +echo "Done! You can enter the chroot using $enterchroot $CHROOT" 1>&2 +echo "If you installed Xfce, you can quickly start it from outside the chroot" 1>&2 +echo "by running ${0%/*}/startxfce4.sh" 1>&2 diff --git a/startxfce4.sh b/startxfce4.sh new file mode 100755 index 000000000..40df7395a --- /dev/null +++ b/startxfce4.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This is an simple script using enter-chroot.sh to start an Xfce session. +# You should enter the chroot and install xfce before running this. +# sudo apt-get install xfce4 xfce4-goodies shimmer-themes +# (xfce4-goodies and shimmer-themes are optional.) + +exec "${0%/*}/enter-chroot.sh" "${1:-precise}" 1000 startxfce4