From patchwork Thu Aug 29 23:46:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 271029 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D03672C0084 for ; Fri, 30 Aug 2013 09:49:38 +1000 (EST) Received: from localhost ([::1]:46460 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBy5-0001KP-24 for incoming@patchwork.ozlabs.org; Thu, 29 Aug 2013 19:49:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43464) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBw7-0006tc-7P for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VFBw5-0005SF-QC for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:35 -0400 Received: from smtp5-g21.free.fr ([2a01:e0c:1:1599::14]:42932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VFBw5-0005Rm-3x for qemu-devel@nongnu.org; Thu, 29 Aug 2013 19:47:33 -0400 Received: from Quad (unknown [IPv6:2a01:e34:eeee:5240:9daa:7271:81b9:90fb]) by smtp5-g21.free.fr (Postfix) with ESMTP id 0C2E1D48037; Fri, 30 Aug 2013 01:47:25 +0200 (CEST) Received: from laurent by Quad with local (Exim 4.80) (envelope-from ) id 1VFBvw-00011A-KW; Fri, 30 Aug 2013 01:47:24 +0200 From: Laurent Vivier To: Riku Voipio Date: Fri, 30 Aug 2013 01:46:45 +0200 Message-Id: <1377820005-3835-7-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1377820005-3835-1-git-send-email-laurent@vivier.eu> References: <1377820005-3835-1-git-send-email-laurent@vivier.eu> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a01:e0c:1:1599::14 Cc: qemu-devel@nongnu.org, Laurent Vivier Subject: [Qemu-devel] [PATCH 6/6] scripts: create a template to use with lxc-create X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Laurent Vivier --- scripts/lxc-cross-debian | 353 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100755 scripts/lxc-cross-debian diff --git a/scripts/lxc-cross-debian b/scripts/lxc-cross-debian new file mode 100755 index 0000000..aded1d3 --- /dev/null +++ b/scripts/lxc-cross-debian @@ -0,0 +1,353 @@ +#!/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() { + qemu=$(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 [ "$qemu" = "$interpreter" ] ; then + echo "$interpreter_path" + return 0 + fi + 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-debian + + return $? +} + +create_root() { + + rootfs="$1" + hostname="$2" + qemu="$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 qemu binary + + if ! cp "$qemu" "$rootfs/$interpreter_path" ; then + echo "ERROR: failed to copy $qemu 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 "${qemu}" |grep -q "statically linked" ; then + echo "ERROR: '${qemu}' must be statically linked" 1>&2 + exit 1 +fi + +interpreter_path=$(find_interpreter "$qemu") +if [ $? -ne 0 ] ; then + echo "ERROR: no binfmt interpreter using $(basename $qemu)" 1>&2 + exit 1 +fi + +rootfs=$(get_rootfs $path) + +create_root "$rootfs" "$name" "$qemu" "$arch" "$interpreter_path" "$include" + +configure_debian "$rootfs" "$name" "$debian_sign" + +create_lxc "$path" "$rootfs" "$name"