#!/bin/bash # Copyright 2006-2007 (C) Canonical Ltd. # Created by Kees Cook # License: GPLv2 # # This script creates LVM snapshot chroots via schroot and sbuild. # Much love to "man sbuild-setup", https://wiki.ubuntu.com/PbuilderHowto, # and https://help.ubuntu.com/community/SbuildLVMHowto. # # It assumes that sbuild has not be installed and configured before. # # If using schroot earlier than 1.1.4-1, it's a good idea to apply the # process-cleaning patch to /etc/schroot/setup.d/10mount. Without this, any # processes left running from the build (like cron, dbus, etc) will stop # schroot from umounting and shutting down cleanly: # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=391319 # # If using sbuild 0.50 or earlier, and you intend to use the "arch" argument # to do i386 builds on amd64, you will need to patch "sbuild" to correctly # detect the chroot architecture: # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=392992 # # Version: 0.12 set -e # Make sure we've got a regular user if [ -w /etc/passwd ]; then echo "Please run this script as a regular user, not root." >&2 exit 1 fi # Perform once-only things to initially set up for using sbuild+schroot+lvm if [ ! -w /var/lib/sbuild ]; then # Load all the packages you'll need to do work sudo apt-get install sbuild schroot debootstrap lvm2 # Make sure LVM tools that operate on the snapshots have needed module sudo modprobe dm_snapshot sudo bash -c "grep ^dm_snapshot /etc/modules >/dev/null || echo dm_snapshot >> /etc/modules" # Add self to the sbuild group sudo adduser "$USER" sbuild # Create some default build/log areas mkdir -p ~/ubuntu/build ~/ubuntu/logs # Prepare a usable default .sbuildrc if [ ! -e ~/.sbuildrc ]; then cat > ~/.sbuildrc <&2 exit 1 fi function usage() { echo "Usage: $0 [OPTIONS] VG Release" >&2 echo "Options:" echo " --arch=ARCH What architecture to select" echo " --name=NAME Base name for the schroot (arch is appended)" echo " --personality=PERSONALITY What personality to use (defaults to match --arch)" echo " --debug Turn on script debugging" echo " --source-template=FILE Use FILE as the sources.list template" echo " --debootstrap-mirror=URL Use URL as the debootstrap source" exit 1 } if [ -z "$1" ]; then usage fi OPTS=`getopt -o '' --long "help,debug,arch:,name:,source-template:,debootstrap-mirror:,personality:" -- "$@"` eval set -- "$OPTS" name="" while :; do case "$1" in --debug) set -x shift ;; --arch) # By default, use the native architecture. arch_opt="--arch $2" arch_suffix="-$2" if [ -z "$personality" -a "$2" = "i386" ] then personality="linux32" fi shift 2 ;; --personality) personality="$2" shift 2 ;; --name) name="$2" shift 2 ;; --source-template) TEMPLATE_SOURCES="$2" shift 2 if [ ! -r $TEMPLATE_SOURCES ]; then echo "W: Template file $TEMPLATE_SOURCES is not readable" echo "W: Continuing with default sources!" fi ;; --debootstrap-mirror) DEBOOTSTRAP_MIRROR="$2" shift 2 ;; --) shift break ;; --help|*) usage ;; esac done # To build the LV, we need to know which volume group to use, and which # release of Ubuntu to debootstrap VG="$1" RELEASE="$2" if [ -z "$VG" ] || [ -z "$RELEASE" ]; then usage fi # By default, name the schroot the same as the release if [ -z "$name" ]; then name="$RELEASE" fi # Set up some variables for use in the paths and names CHROOT_LV="${name}_chroot${arch_suffix}" CHROOT_PATH="/dev/$VG/$CHROOT_LV" CHROOT_NAME="${name}${arch_suffix}" # Does the specified VG exist? (vgdisplay doesn't set error codes...) if [ `sudo vgdisplay -c "$VG" | wc -l` -eq 0 ]; then exit 1 fi # Is the specified release known to debootstrap? if [ ! -r "/usr/share/debootstrap/scripts/$RELEASE" ]; then echo "Specified release not known to debootstrap" >&2 exit 1 else variant_opt="--variant=buildd" fi # Allocate the "golden" chroot LV sudo lvcreate -n "$CHROOT_LV" -L 5G "$VG" sudo mkfs -t ext3 "$CHROOT_PATH" # Mount and debootstrap the chroot MNT=`mktemp -d -t schroot-XXXXXX` sudo mount "$CHROOT_PATH" "$MNT" sudo debootstrap $arch_opt $variant_opt "$RELEASE" "$MNT" "${DEBOOTSTRAP_MIRROR:-http://archive.ubuntu.com/ubuntu}" # Update the package sources TEMP_SOURCES=`mktemp -t sources-XXXXXX` if [ -z "$TEMPLATE_SOURCES" ]; then TEMPLATE_SOURCES=~/.mk-sbuild-lv.sources fi if [ -r "$TEMPLATE_SOURCES" ]; then cat "$TEMPLATE_SOURCES" > "$TEMP_SOURCES" else cat > "$TEMP_SOURCES" < $MNT/etc/apt/sources.list" rm -f "$TEMP_SOURCES" # Copy the timezone (comment this out if you want to leave the chroot at UTC) sudo cp /etc/localtime /etc/timezone "$MNT"/etc/ # Create an LVM-snapshot-based schroot entry for this LV TEMP_SCHROOTCONF=`mktemp -t schrootconf-XXXXXX` TEMPLATE_SCHROOTCONF=~/.mk-sbuild-lv.schroot.conf if [ -r "$TEMPLATE_SCHROOTCONF" ]; then cat "$TEMPLATE_SCHROOTCONF" > "$TEMP_SCHROOTCONF" else cat > "$TEMP_SCHROOTCONF" <> "$TEMP_SCHROOTCONF" fi cat "$TEMP_SCHROOTCONF" | sed \ -e "s|CHROOT_NAME|$CHROOT_NAME|g" \ -e "s|CHROOT_PATH|$CHROOT_PATH|g" \ | \ sudo bash -c "cat >> /etc/schroot/schroot.conf" rm -f "$TEMP_SCHROOTCONF" # Create image finalization script BUILD_PKGS="build-essential fakeroot devscripts" # Add edgy+ buildd tools if [ "$RELEASE" != "breezy" ] && [ "$RELEASE" != "dapper" ]; then BUILD_PKGS="$BUILD_PKGS pkg-create-dbgsym pkgbinarymangler" fi sudo bash -c "cat >> $MNT/finish.sh" <