Message ID | 1358637660-8625-3-git-send-email-laurent@vivier.eu |
---|---|
State | New |
Headers | show |
On 20.01.2013, at 00:21, Laurent Vivier wrote: > sudo qemu-create-lxc.sh <target> > > This script mixes linux container, binfmt and qemu to create hybrid linux > container : <target> container on an host kernel. > > It will create "light" emulated virtual machine with several steps : > - create a linux-user qemu-<target> > - define it as the binfmt interpreter (using qemu-update-binfmt). > - install a base debian system under /containers/<target> using debootstrap. > and set a minimal configuration. > - define a linux container > > Then you can start the container using : sudo lxc-start -n virt<target> > > 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 <laurent@vivier.eu> > --- > 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 \ I don't think anything running debootstrap belongs in generically sounding QEMU source code. Alex
Le jeudi 24 janvier 2013 à 19:05 +0100, Alexander Graf a écrit : > On 20.01.2013, at 00:21, Laurent Vivier wrote: [...] > > +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 \ > > I don't think anything running debootstrap belongs in generically > sounding QEMU source code. Why ? As I said, these scripts are helper scripts for developers. If someone wants to use this with Fedora/RHEL distro, it is to him to add the "febootstrap" part. BTW, I don't know if there is this kind of tool for SUSE. Regards, Laurent
Am 24.01.2013 um 21:16 schrieb Laurent Vivier <Laurent@vivier.eu>: > Le jeudi 24 janvier 2013 à 19:05 +0100, Alexander Graf a écrit : >> On 20.01.2013, at 00:21, Laurent Vivier wrote: > [...] >>> +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 \ >> >> I don't think anything running debootstrap belongs in generically >> sounding QEMU source code. > > Why ? Because it's a QEMU script. If you like, add a separate debian-create-rootfs script that you can call from this one. Then it's properly separated. > As I said, these scripts are helper scripts for developers. If someone > wants to use this with Fedora/RHEL distro, it is to him to add the > "febootstrap" part. BTW, I don't know if there is this kind of tool for > SUSE. That would be "kiwi". :) Alex > > Regards, > Laurent > -- > "Just play. Have fun. Enjoy the game." > - Michael Jordan >
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 <<!EOF +# <file system> <mount point> <type> <options> <dump> <pass> +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 <<!EOF +auto eth0 +iface eth0 inet dhcp +!EOF + + cat >> ${CONTAINER_PATH}/etc/apt/sources.list <<!EOF +deb ${DEBIAN_REPO} ${DEBIAN_DIST} main contrib non-free +deb-src ${DEBIAN_REPO} ${DEBIAN_DIST} main contrib non-free +!EOF + + rm -f ${CONTAINER_PATH}/dev/ptmx + + if [ "$DEBIAN_SIGN" != "" ] + then + HOME=/root chroot ${CONTAINER_PATH} gpg --keyserver pgpkeys.mit.edu --recv-key ${DEBIAN_SIGN} + HOME=/root chroot ${CONTAINER_PATH} gpg -a --export ${DEBIAN_SIGN} | chroot ${CONTAINER_PATH} apt-key add - + fi + chroot ${CONTAINER_PATH} apt-get update + chroot ${CONTAINER_PATH} dpkg-reconfigure tzdata + chroot ${CONTAINER_PATH} apt-get install locales + chroot ${CONTAINER_PATH} dpkg-reconfigure locales + chroot ${CONTAINER_PATH} passwd +} + +create_lxc() { + cat > ${LXC_CONF} <<!EOF +lxc.utsname = ${CONTAINER_NAME} + +lxc.network.type = veth +lxc.network.flags = up +lxc.network.link = lxcbr0 +lxc.network.name = eth0 + +lxc.pts=1023 +lxc.tty=12 + +lxc.rootfs = ${CONTAINER_PATH} + +lxc.cgroup.devices.deny = a +lxc.cgroup.devices.allow = c 136:* rwm # pts +lxc.cgroup.devices.allow = c 254:0 rwm # rtc +lxc.cgroup.devices.allow = c 5:* rwm +lxc.cgroup.devices.allow = c 4:* rwm # ttyXX +lxc.cgroup.devices.allow = c 1:* rwm +lxc.cgroup.devices.allow = b 7:* rwm # loop +lxc.cgroup.devices.allow = b 1:* rwm # ram + +!EOF + lxc-create -n ${CONTAINER_NAME} -f ${LXC_CONF} +} + +TARGET="$1" + +if [ "$TARGET" = "" ] +then + echo "ERROR: you must provide a target." 1>&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}"
sudo qemu-create-lxc.sh <target> This script mixes linux container, binfmt and qemu to create hybrid linux container : <target> container on an host kernel. It will create "light" emulated virtual machine with several steps : - create a linux-user qemu-<target> - define it as the binfmt interpreter (using qemu-update-binfmt). - install a base debian system under /containers/<target> using debootstrap. and set a minimal configuration. - define a linux container Then you can start the container using : sudo lxc-start -n virt<target> 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 <laurent@vivier.eu> --- scripts/qemu-create-lxc.sh | 280 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100755 scripts/qemu-create-lxc.sh