#!/bin/bash # # Some parts from lxc-debian, Daniel Lezcano # # Copy this script to /usr/share/lxc/templates # # and use it with # lxc-create -t cross-debian -n xxxx -- --arch xxx --interpreter-path /a/b/c/qemu-xxx # SUITE=${SUITE:-stable} MIRROR=${MIRROR:-http://ftp.debian.org/debian} find_interpreter() { given_interpreter=$(basename "$1") if [ ! -d /proc/sys/fs/binfmt_misc/ ] ; then return 1 fi for file in /proc/sys/fs/binfmt_misc/* ; do if [ "$file" = "/proc/sys/fs/binfmt_misc/register" -o \ "$file" = "/proc/sys/fs/binfmt_misc/status" ] ; then continue fi interpreter_path=$(sed -n "/^interpreter/s/interpreter \([^[:space:]]*\)/\1/p" "$file") interpreter=$(basename $interpreter_path) if [ "$given_interpreter" = "$interpreter" ] ; then echo "$interpreter_path" return 0 fi set +x done return 1 } download_debian() { cache="$1" arch="$2" if [ ! -d "$cache/archives-$SUITE-$arch" ]; then if ! mkdir -p "$cache/archives-$SUITE-$arch" ; then echo "Failed to create '$cache/archives-$SUITE-$arch' directory" return 1 fi fi echo "Downloading debian $SUITE $arch..." if ! debootstrap --download-only \ --no-check-gpg \ --arch=$arch \ --include="locales" \ ${SUITE} "$cache/archives-$SUITE-$arch" \ ${MIRROR} ; then echo "ERROR: failed to download to $cache/archives-$SUITE-$arch" 1>&2 exit 1 fi echo "Download complete." trap EXIT trap SIGINT trap SIGTERM trap SIGHUP return 0 } copy_debian() { cache=$1 arch=$2 rootfs=$3 echo -n "Copying rootfs to $rootfs..." mkdir -p $rootfs rsync -Ha "$cache/archives-$SUITE-$arch"/ $rootfs/ || return 1 echo "Copy complete." return 0 } install_debian() { cache="/var/cache/lxc/debian" rootfs="$1" arch="$2" mkdir -p /var/lock/subsys/ ( if ! flock -x 200 ; then echo "Cache repository is busy." return 1 fi if ! download_debian $cache $arch ; then echo "Failed to download 'debian base'" return 1 fi if ! copy_debian $cache $arch $rootfs ; then echo "Failed to copy rootfs" return 1 fi return 0 ) 200>/var/lock/subsys/lxc-cross-debian return $? } create_root() { rootfs="$1" hostname="$2" interpreter="$3" arch="$4" interpreter_path="$5" include="$6" if ! install_debian "$rootfs" "$arch" ; then echo "ERROR: failed to update cache" 1>&2 exit 1 fi if [ "${include}" = "" ] ; then include="locales" else include="locales,${include}" fi # Debian bootstrap if ! debootstrap --no-check-gpg --foreign \ --arch=$arch \ --include="${include}" \ ${SUITE} "$rootfs" \ ${MIRROR} ; then echo "ERROR: failed to debootstrap to $rootfs" 1>&2 exit 1 fi # adding interpreter binary if ! cp "$interpreter" "$rootfs/$interpreter_path" ; then echo "ERROR: failed to copy $interpreter to $rootfs/$interpreter_path" 1>&2 exit 1 fi # debian bootstrap second stage chroot "$rootfs" debootstrap/debootstrap --second-stage } configure_debian() { rootfs="$1" hostname="$2" debian_sign="$3" # set timezone cat /etc/timezone > "$rootfs/etc/timezone" chroot $rootfs dpkg-reconfigure -fnoninteractive tzdata # configuration cat >> "$rootfs/etc/fstab" < devpts /dev/pts devpts nodev,noexec,nosuid 0 1 !EOF echo "$hostname" > "$rootfs/etc/hostname" echo "c:2345:respawn:/sbin/getty 38400 console" >> "$rootfs/etc/inittab" cat >> "$rootfs/etc/network/interfaces" < "$rootfs/etc/apt/sources.list" < "$rootfs/etc/locale.gen" chroot $rootfs locale-gen chroot $rootfs update-locale LANG=en_US.UTF-8 else echo "$LANG $(echo $LANG | cut -d. -f2)" > "$rootfs/etc/locale.gen" chroot $rootfs locale-gen chroot $rootfs update-locale LANG=$LANG fi # remove pointless services in a container if [ -x "$rootfs/usr/sbin/update-rc.d" ] ; then chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove chroot $rootfs /usr/sbin/update-rc.d -f module-init-tools remove fi echo "root:root" | chroot $rootfs chpasswd echo "Root password is 'root', please change !" } get_rootfs() { config="$1/config" rootfs=$(sed -n "s/^lxc.rootfs[[:space:]]*=[[:space:]]*\(.*\)/\1/p" $config) if [ "$rootfs" = "" ] then echo "$path/rootfs" else echo "$rootfs" fi } create_lxc() { path="$1" rootfs="$2" hostname="$3" grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> "$path/config" cat >> "$path/config" <&2 exit 1 fi } usage() { cat <&2 usage exit 1 fi if ! type debootstrap ; then echo "ERROR: 'debootstrap' command is missing" 1>&2 exit 1 fi if ! file -b "${interpreter}" |grep -q "statically linked" ; then echo "ERROR: '${interpreter}' must be statically linked" 1>&2 exit 1 fi interpreter_path=$(find_interpreter "$interpreter") if [ $? -ne 0 ] ; then echo "ERROR: no binfmt interpreter using $(basename $interpreter)" 1>&2 exit 1 fi if [ "$rootfs" = "" ] ; then rootfs=$(get_rootfs $path) fi create_root "$rootfs" "$name" "$interpreter" "$arch" "$interpreter_path" "$include" configure_debian "$rootfs" "$name" "$debian_sign" create_lxc "$path" "$rootfs" "$name"