From patchwork Sat Jan 19 23:21:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 213888 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3F3582C0084 for ; Sun, 20 Jan 2013 10:21:58 +1100 (EST) Received: from localhost ([::1]:60480 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TwhjY-0004Sx-9x for incoming@patchwork.ozlabs.org; Sat, 19 Jan 2013 18:21:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:45916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TwhjF-0004Fv-Er for qemu-devel@nongnu.org; Sat, 19 Jan 2013 18:21:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TwhjD-0004XT-8y for qemu-devel@nongnu.org; Sat, 19 Jan 2013 18:21:37 -0500 Received: from smtp6-g21.free.fr ([2a01:e0c:1:1599::15]:36882) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TwhjC-0004XG-KB for qemu-devel@nongnu.org; Sat, 19 Jan 2013 18:21:35 -0500 Received: from localhost.localdomain (unknown [78.238.229.36]) by smtp6-g21.free.fr (Postfix) with ESMTP id 3EFF382270; Sun, 20 Jan 2013 00:21:29 +0100 (CET) From: Laurent Vivier To: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 20 Jan 2013 00:21:00 +0100 Message-Id: <1358637660-8625-3-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1358637660-8625-1-git-send-email-laurent@vivier.eu> References: <1358199410-19033-1-git-send-email-laurent@vivier.eu> <1358637660-8625-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::15 Cc: Laurent Vivier , Riku Voipio , qemu-devel@nongnu.org, Alexander Graf Subject: [Qemu-devel] [PATCH 3/3] scripts: A script to create linux container using qemu-linux-user. 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 sudo qemu-create-lxc.sh This script mixes linux container, binfmt and qemu to create hybrid linux container : container on an host kernel. It will create "light" emulated virtual machine with several steps : - create a linux-user qemu- - define it as the binfmt interpreter (using qemu-update-binfmt). - install a base debian system under /containers/ using debootstrap. and set a minimal configuration. - define a linux container Then you can start the container using : sudo lxc-start -n virt TARGETS STATUS: alpha: cannot run debootstrap --second stage*, but chroot is usable m68k: need patches from qemu-m68k, after that, all is working fine. mips: container can be started, but console login hangs. ppc: works fine* sparc: cannot run debootstrap --second stage (cannot fork) raspberrypi: (=armhf+raspbian) works* * needs patches I sent to the mailing-list previously Signed-off-by: Laurent Vivier --- scripts/qemu-create-lxc.sh | 280 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100755 scripts/qemu-create-lxc.sh diff --git a/scripts/qemu-create-lxc.sh b/scripts/qemu-create-lxc.sh new file mode 100755 index 0000000..4d51e61 --- /dev/null +++ b/scripts/qemu-create-lxc.sh @@ -0,0 +1,280 @@ +QEMU_PATH=$(dirname $(dirname $(readlink -f $0))) + +TARGET_LIST="i386 m68k alpha sparc mips ppc raspberrypi" + +set_i386() { + : nothing specific +} + +set_m68k() { + DEBIAN_REPO=http://archive.debian.org/debian + DEBIAN_DIST=etch-m68k + DEBIAN_SIGN=55BE302B + + CONFIGURE_PARAMS=--m68k-default-cpu=m68040 +} + +set_alpha() { + DEBIAN_REPO=http://archive.debian.org/debian + DEBIAN_DIST=lenny +} + +set_sparc() { + QEMU_TARGET=sparc32plus +} + +set_mips() { + : nothing specific +} + +set_ppc() { + DEBIAN_TARGET=powerpc +} + +set_raspberrypi() { + DEBIAN_REPO=http://archive.raspbian.org/raspbian + DEBIAN_DIST=wheezy + DEBIAN_SIGN="" + DEBIAN_TARGET=armhf + QEMU_TARGET=arm +} + +check_target() { + found=0 + for available in $TARGET_LIST + do + if [ "$available" = "$TARGET" ] + then + found=1 + break; + fi + done + if [ $found -eq 0 ] + then + echo "ERROR: unknown target $TARGET" 1>&2 + exit 1 + fi + + # generic values + + CONTAINER_NAME=virt${TARGET} + CONTAINER_PATH=/containers/${TARGET} + LXC_CONF=$HOME/lxc-${TARGET}.conf + + DEBIAN_REPO=http://ftp.debian.org/debian + DEBIAN_DIST=stable + DEBIAN_SIGN="" + DEBIAN_TARGET=$TARGET + + QEMU_TARGET=$TARGET + + CHECK_BIN=check_default + + # target specific values + + set_$TARGET + + QEMU_BIN=${QEMU_PATH}/build-${QEMU_TARGET}/${QEMU_TARGET}-linux-user/qemu-${QEMU_TARGET} +} + +check_m68k() { + if ${QEMU_BIN} -cpu help | grep -q ">m68040" + then + echo "Found an existing qemu-m68k, use it !" 1>&2 + return 0 + fi + echo "Found an existing qemu-m68k, but with no m68040 emulation" 1>&2 + echo "Please, remove it" 1>&2 + echo "m68040 emulation is available from " 1>&2 + echo "git clone git://gitorious.org/qemu-m68k/qemu-m68k.git" + exit 1 +} + +check_default() { + test -e ${QEMU_BIN} +} + +installed_dpkg() { + dpkg --status "$1" > /dev/null 2>&1 +} + +check_env() { + if [ ! -e /etc/debian_version ] + then + echo "ERROR: this script works only on Debian based distro" 1>&2 + exit 1 + fi + for pkg in zlib1g gcc make debootstrap lxc + do + if ! installed_dpkg $pkg + then + echo "ERROR: $pkg is needed" 1>&2 + exit 1 + fi + done +} + +create_qemu() { + if [ -e "${QEMU_BIN}" ] + then + if ${CHECK_BIN} + then + return 0 + fi + fi + echo "cd ${QEMU_PATH} && \ + mkdir build-${QEMU_TARGET} && \ + cd build-${QEMU_TARGET} && \ + ../configure --static ${CONFIGURE_PARAMS} \ + --target-list=${QEMU_TARGET}-linux-user && \ + make" | sudo -i -u ${SUDO_USER} + if ! ${CHECK_BIN} + then + echo "ERROR: generated qemu binary is invalid !" 1>&2 + exit 1 + fi +} + +create_root() { + # sanity check + + if [ $(readlink -f ${CONTAINER_PATH}/) = "/" ] + then + echo "ERROR: invalid path ${CONTAINER_PATH}" 1>&2 + exit 1 + fi + + # check directory + + if [ -e "${CONTAINER_PATH}" ] + then + echo "${CONTAINER_PATH} already exists" 1>&2 + echo "Please, remove it" 1>&2 + exit 1 + fi + + # Debian bootstrap + + mkdir -p "${CONTAINER_PATH}" + debootstrap --foreign \ + --arch=${DEBIAN_TARGET} \ + ${DEBIAN_DIST} ${CONTAINER_PATH} \ + ${DEBIAN_REPO} && \ + + # adding qemu binary + + cp ${QEMU_BIN} ${CONTAINER_PATH}/bin && \ + ${QEMU_PATH}/scripts/qemu-update-binfmt ${QEMU_TARGET} /bin + + # debian bootstrap second stage + + chroot ${CONTAINER_PATH} debootstrap/debootstrap --second-stage + + # configuration + + cat >> ${CONTAINER_PATH}/etc/fstab < +proc /proc proc nodev,noexec,nosuid 0 1 +devpts /dev/pts devpts nodev,noexec,nosuid 0 1 +!EOF + + echo "$CONTAINER_NAME" > ${CONTAINER_PATH}/etc/hostname + echo "c:2345:respawn:/sbin/getty 38400 console" >> ${CONTAINER_PATH}/etc/inittab + + cat >> ${CONTAINER_PATH}/etc/network/interfaces <> ${CONTAINER_PATH}/etc/apt/sources.list < ${LXC_CONF} <&2 + echo " Available targets are:" 1>&2 + echo " $TARGET_LIST" + exit 1 +fi + + +check_env +check_target + +echo "DEBIAN_TARGET : ${DEBIAN_TARGET}" +echo "QEMU_TARGET : ${QEMU_TARGET}" +echo "CONTAINER_NAME: ${CONTAINER_NAME}" +echo "CONTAINER_PATH: ${CONTAINER_PATH}" +echo "QEMU_PATH : ${QEMU_PATH}" +echo "LXC_CONF : ${LXC_CONF}" +echo "DEBIAN_REPO : ${DEBIAN_REPO}" +echo "DEBIAN_DIST : ${DEBIAN_DIST}" + +if lxc-list | grep -q ${CONTAINER_NAME} +then + echo "${CONTAINER_NAME} already exists !" 1>&2 + echo "you can remove it with :" 1>&2 + echo " sudo lxc-destroy -n ${CONTAINER_NAME}" 1>&2 + echo "[WARNING: this will remove the directory too]" 1>&2 + exit 2 +fi + +if [ "$USER" != "root" ] +then + echo "You need to be root to run this command" 2>&1 + exit 3 +fi + +create_qemu +create_root +create_lxc + +chroot ${CONTAINER_PATH} uname -a + +echo "you can now start your container using:" +echo " sudo lxc-start -n ${CONTAINER_NAME}"