qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: Riku Voipio <riku.voipio@iki.fi>
Cc: qemu-devel@nongnu.org, Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH 6/6] scripts: create a template to use with lxc-create
Date: Fri, 30 Aug 2013 01:46:45 +0200	[thread overview]
Message-ID: <1377820005-3835-7-git-send-email-laurent@vivier.eu> (raw)
In-Reply-To: <1377820005-3835-1-git-send-email-laurent@vivier.eu>

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 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 <daniel.lezcano@free.fr>
+#
+# 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" <<!EOF
+# <file system> <mount point>   <type>  <options>       <dump>  <pass>
+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" <<!EOF
+auto eth0
+iface eth0 inet dhcp
+!EOF
+
+    cat > "$rootfs/etc/apt/sources.list" <<!EOF
+deb ${MIRROR} ${SUITE} main contrib non-free
+#deb-src ${MIRROR} ${SUITE} main contrib non-free
+!EOF
+
+    if [ "$debian_sign" != "" ]
+    then
+        HOME=/root chroot "$rootfs" gpg --keyserver pgpkeys.mit.edu --recv-key ${debian_sign}
+        HOME=/root chroot "$rootfs" gpg -a --export ${debian_sign} | chroot "$rootfs"  apt-key add -
+    fi
+
+    chroot "$rootfs" apt-get update
+
+    if [ -z "$LANG" ]; then
+        echo "en_US.UTF-8 UTF-8" > "$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" <<!EOF
+lxc.utsname = $hostname
+
+lxc.pts=1023
+lxc.tty=12
+
+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
+
+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
+lxc.mount.entry=sysfs sys sysfs defaults  0 0
+
+!EOF
+    if [ $? -ne 0 ] ; then
+        echo "ERROR: failed to create LXC configuration" 1>&2
+        exit 1
+    fi
+}
+
+usage()
+{
+    cat <<!EOF
+Usage: $1 --path PATH --name NAME --arch ARCH --interpreter-path QEMU
+          [--mirror MIRROR][--suite SUITE]
+
+    --path is configuration path
+    --name is container name
+    --arch is debian architecture
+    --interpreter-path is path to the interpreter to copy to rootfs
+    --mirror is URL of debian mirror to use
+    --suite is debian suite to install
+    --include is the list of package to add to debootstrap
+!EOF
+}
+
+options=$(getopt -o hp:n:I:a:s:m:k:i: -l help,path:,name:,interpreter-path:,arch:,suite:,mirror:,deb-sign:,include: -- "$@")
+if [ $? -ne 0 ]; then
+        usage $(basename $0)
+        exit 1
+fi
+eval set -- "$options"
+
+while true ; do
+    case "$1" in
+    -p|--path)
+        shift
+        path="$1"
+        ;;
+    -n|--name)
+        shift
+        name="$1"
+        ;;
+    -a|--arch)
+        shift
+        arch="$1"
+        ;;
+    -I|--interpreter-path)
+        shift
+        qemu="$1"
+        ;;
+    -s|--suite)
+        shift
+        SUITE="$1"
+        ;;
+    -m|--mirror)
+        shift
+        MIRROR="$1"
+        ;;
+    -i|--include)
+        shift
+        include="$1"
+        ;;
+    -k|--deb-sign)
+        shift
+        debian_sign="$1"
+        ;;
+    -h|--help)
+        usage
+        exit 1
+        ;;
+    *)
+        break
+        ;;
+    esac
+    shift
+done
+
+if [ "$path" = "" -o "$name" = "" -o "$arch" = "" -o "$qemu" = "" ] ; then
+    echo "ERROR: missing parameter" 1>&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"
-- 
1.8.1.2

  parent reply	other threads:[~2013-08-29 23:47 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-29 23:46 [Qemu-devel] [PATCH 0/6] linux-user: Misc patches for linux container compatibility Laurent Vivier
2013-08-29 23:46 ` [Qemu-devel] [PATCH 1/6] linux-user: convert /proc/net/route when endianess differs Laurent Vivier
2013-09-06 16:30   ` Peter Maydell
2013-08-29 23:46 ` [Qemu-devel] [PATCH 2/6] linux-user: Add setsockopt(SO_ATTACH_FILTER) Laurent Vivier
2013-09-06 16:30   ` Peter Maydell
2013-08-29 23:46 ` [Qemu-devel] [PATCH 3/6] linux-user: allow use of TIOCGSID Laurent Vivier
2013-09-06 16:31   ` Peter Maydell
2013-08-29 23:46 ` [Qemu-devel] [PATCH 4/6] linux-user: add some IPV6 commands in setsockop() Laurent Vivier
2013-09-06 16:31   ` Peter Maydell
2013-08-29 23:46 ` [Qemu-devel] [PATCH 5/6] linux-user: add support of binfmt_misc 'O' flag Laurent Vivier
2013-09-06 16:17   ` Peter Maydell
2013-09-06 16:50     ` Laurent Vivier
2013-08-29 23:46 ` Laurent Vivier [this message]
2013-09-06 16:33   ` [Qemu-devel] [PATCH 6/6] scripts: create a template to use with lxc-create Peter Maydell
2013-09-06 16:56     ` Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1377820005-3835-7-git-send-email-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).