[lxc-devel] [PATCH 3/4] lxc-ubuntu: Rename from lxc-ubuntu.in

Stéphane Graber stgraber at ubuntu.com
Thu Nov 29 15:11:39 UTC 2012


On 11/29/2012 09:52 AM, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
>> lxc-ubuntu no longer uses any build time variables, therefore it can
>> now be simply copied to the target without any autoconf magic.
>>
>> Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
> 
> I'm trusting rather than verifying that the contents of
> lxc-ubuntu are identical to lxc-ubuntu.in?  :)

Hehe, yeah, was just a simple "git mv", I wish git could somehow
indicate that in the diff...

> It could certainly be argued that it's preferable to handle
> all the templates the same way.  What would you say is the
> advantage of doing this?

The main advantage for me is that when I see a template ending with .in
I do a full local test build and then try the template locally as it's
supposed to contain variables.
If it doesn't, I just run lxc-create -t <path> and I save a good 5
minutes :)


>> ---
>>  configure.ac            |   1 -
>>  templates/lxc-ubuntu    | 729 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  templates/lxc-ubuntu.in | 729 ------------------------------------------------
>>  3 files changed, 729 insertions(+), 730 deletions(-)
>>  create mode 100644 templates/lxc-ubuntu
>>  delete mode 100644 templates/lxc-ubuntu.in
>>
>> diff --git a/configure.ac b/configure.ac
>> index 5f0cc0b..b73e07b 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -244,7 +244,6 @@ AC_CONFIG_FILES([
>>  	templates/Makefile
>>  	templates/lxc-lenny
>>  	templates/lxc-debian
>> -	templates/lxc-ubuntu
>>  	templates/lxc-ubuntu-cloud
>>  	templates/lxc-opensuse
>>  	templates/lxc-busybox
>> diff --git a/templates/lxc-ubuntu b/templates/lxc-ubuntu
>> new file mode 100644
>> index 0000000..ce1e065
>> --- /dev/null
>> +++ b/templates/lxc-ubuntu
>> @@ -0,0 +1,729 @@
>> +#!/bin/bash
>> +
>> +#
>> +# template script for generating ubuntu container for LXC
>> +#
>> +# This script consolidates and extends the existing lxc ubuntu scripts
>> +#
>> +
>> +# Copyright ? 2011 Serge Hallyn <serge.hallyn at canonical.com>
>> +# Copyright ? 2010 Wilhelm Meier
>> +# Author: Wilhelm Meier <wilhelm.meier at fh-kl.de>
>> +#
>> +# This program is free software; you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License version 2, as
>> +# published by the Free Software Foundation.
>> +
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +# GNU General Public License for more details.
>> +
>> +# You should have received a copy of the GNU General Public License along
>> +# with this program; if not, write to the Free Software Foundation, Inc.,
>> +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> +#
>> +
>> +set -e
>> +
>> +if [ -r /etc/default/lxc ]; then
>> +    . /etc/default/lxc
>> +fi
>> +
>> +configure_ubuntu()
>> +{
>> +    rootfs=$1
>> +    hostname=$2
>> +    release=$3
>> +
>> +   # configure the network using the dhcp
>> +    cat <<EOF > $rootfs/etc/network/interfaces
>> +# This file describes the network interfaces available on your system
>> +# and how to activate them. For more information, see interfaces(5).
>> +
>> +# The loopback network interface
>> +auto lo
>> +iface lo inet loopback
>> +
>> +auto eth0
>> +iface eth0 inet dhcp
>> +EOF
>> +
>> +    # set the hostname
>> +    cat <<EOF > $rootfs/etc/hostname
>> +$hostname
>> +EOF
>> +    # set minimal hosts
>> +    cat <<EOF > $rootfs/etc/hosts
>> +127.0.0.1   localhost
>> +127.0.1.1   $hostname
>> +
>> +# The following lines are desirable for IPv6 capable hosts
>> +::1     ip6-localhost ip6-loopback
>> +fe00::0 ip6-localnet
>> +ff00::0 ip6-mcastprefix
>> +ff02::1 ip6-allnodes
>> +ff02::2 ip6-allrouters
>> +EOF
>> +
>> +    if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> +        # suppress log level output for udev
>> +        sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
>> +
>> +        # remove jobs for consoles 5 and 6 since we only create 4 consoles in
>> +        # this template
>> +        rm -f $rootfs/etc/init/tty{5,6}.conf
>> +    fi
>> +
>> +    if [ -z "$bindhome" ]; then
>> +        chroot $rootfs useradd --create-home -s /bin/bash ubuntu
>> +        echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
>> +    fi
>> +
>> +    # make sure we have the current locale defined in the container
>> +    if [ -z "$LANG" ]; then
>> +        chroot $rootfs locale-gen en_US.UTF-8
>> +        chroot $rootfs update-locale LANG=en_US.UTF-8
>> +    else
>> +        chroot $rootfs locale-gen $LANG
>> +        chroot $rootfs update-locale LANG=$LANG
>> +    fi
>> +
>> +    return 0
>> +}
>> +
>> +# finish setting up the user in the container by injecting ssh key and
>> +# adding sudo group membership.
>> +# passed-in user is either 'ubuntu' or the user to bind in from host.
>> +finalize_user()
>> +{
>> +    user=$1
>> +
>> +    sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
>> +
>> +    if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
>> +        groups="sudo"
>> +    else
>> +        groups="sudo admin"
>> +    fi
>> +
>> +    for group in $groups; do
>> +        chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
>> +        chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
>> +    done
>> +
>> +    if [ -n "$auth_key" -a -f "$auth_key" ]; then
>> +	u_path="/home/${user}/.ssh"
>> +	root_u_path="$rootfs/$u_path"
>> +	mkdir -p $root_u_path
>> +	cp $auth_key "$root_u_path/authorized_keys"
>> +	chroot $rootfs chown -R ${user}: "$u_path"
>> +
>> +	echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
>> +    fi
>> +    return 0
>> +}
>> +
>> +write_sourceslist()
>> +{
>> +    # $1 => path to the rootfs
>> +    # $2 => architecture we want to add
>> +    # $3 => whether to use the multi-arch syntax or not
>> +
>> +    case $2 in
>> +      amd64|i386)
>> +            MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
>> +            SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
>> +            ;;
>> +      *)
>> +            MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> +            SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> +            ;;
>> +    esac
>> +    if [ -n "$3" ]; then
>> +        cat >> "$1/etc/apt/sources.list" << EOF
>> +deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
>> +deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
>> +deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> +EOF
>> +    else
>> +        cat >> "$1/etc/apt/sources.list" << EOF
>> +deb $MIRROR ${release} main restricted universe multiverse
>> +deb $MIRROR ${release}-updates main restricted universe multiverse
>> +deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> +EOF
>> +    fi
>> +}
>> +
>> +cleanup()
>> +{
>> +    rm -rf $cache/partial-$arch
>> +    rm -rf $cache/rootfs-$arch
>> +}
>> +
>> +suggest_flush()
>> +{
>> +    echo "Container upgrade failed.  The container cache may be out of date,"
>> +    echo "in which case flushing the case (see -F in the hep output) may help."
>> +}
>> +
>> +download_ubuntu()
>> +{
>> +    cache=$1
>> +    arch=$2
>> +    release=$3
>> +
>> +    packages=vim,ssh
>> +
>> +    # Try to guess a list of langpacks to install
>> +    langpacks="language-pack-en"
>> +
>> +    if which dpkg >/dev/null 2>&1; then
>> +        langpacks=`(echo $LANGPACK_LIST &&
>> +                    dpkg -l | grep -E "^ii  language-pack-[a-z]* " |
>> +                        cut -d ' ' -f3) | sort -u`
>> +    fi
>> +    packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
>> +
>> +
>> +    echo "installing packages: $packages"
>> +
>> +    trap cleanup EXIT SIGHUP SIGINT SIGTERM
>> +    # check the mini ubuntu was not already downloaded
>> +    mkdir -p "$cache/partial-$arch"
>> +    if [ $? -ne 0 ]; then
>> +        echo "Failed to create '$cache/partial-$arch' directory"
>> +        return 1
>> +    fi
>> +
>> +    # download a mini ubuntu into a cache
>> +    echo "Downloading ubuntu $release minimal ..."
>> +    if [ -n "$(which qemu-debootstrap)" ]; then
>> +        qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> +    else
>> +        debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> +    fi
>> +
>> +    if [ $? -ne 0 ]; then
>> +        echo "Failed to download the rootfs, aborting."
>> +            return 1
>> +    fi
>> +
>> +    # Serge isn't sure whether we should avoid doing this when
>> +    # $release == `distro-info -d`
>> +    echo "Installing updates"
>> +    > $cache/partial-$arch/etc/apt/sources.list
>> +    write_sourceslist $cache/partial-$arch/ $arch
>> +
>> +    chroot "$1/partial-${arch}" apt-get update
>> +    if [ $? -ne 0 ]; then
>> +        echo "Failed to update the apt cache"
>> +        return 1
>> +    fi
>> +    cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
>> +#!/bin/sh
>> +exit 101
>> +EOF
>> +    chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> +
>> +    lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; }
>> +    rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> +
>> +    chroot "$1/partial-${arch}" apt-get clean
>> +
>> +    mv "$1/partial-$arch" "$1/rootfs-$arch"
>> +    trap EXIT
>> +    trap SIGINT
>> +    trap SIGTERM
>> +    trap SIGHUP
>> +    echo "Download complete"
>> +    return 0
>> +}
>> +
>> +copy_ubuntu()
>> +{
>> +    cache=$1
>> +    arch=$2
>> +    rootfs=$3
>> +
>> +    # make a local copy of the miniubuntu
>> +    echo "Copying rootfs to $rootfs ..."
>> +    mkdir -p $rootfs
>> +    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
>> +    return 0
>> +}
>> +
>> +install_ubuntu()
>> +{
>> +    rootfs=$1
>> +    release=$2
>> +    flushcache=$3
>> +    cache="/var/cache/lxc/$release"
>> +    mkdir -p /var/lock/subsys/
>> +
>> +    (
>> +        flock -x 200
>> +        if [ $? -ne 0 ]; then
>> +            echo "Cache repository is busy."
>> +            return 1
>> +        fi
>> +
>> +
>> +        if [ $flushcache -eq 1 ]; then
>> +            echo "Flushing cache..."
>> +            rm -rf "$cache/partial-$arch"
>> +            rm -rf "$cache/rootfs-$arch"
>> +        fi
>> +
>> +        echo "Checking cache download in $cache/rootfs-$arch ... "
>> +        if [ ! -e "$cache/rootfs-$arch" ]; then
>> +            download_ubuntu $cache $arch $release
>> +            if [ $? -ne 0 ]; then
>> +                echo "Failed to download 'ubuntu $release base'"
>> +                return 1
>> +            fi
>> +        fi
>> +
>> +        echo "Copy $cache/rootfs-$arch to $rootfs ... "
>> +        copy_ubuntu $cache $arch $rootfs
>> +        if [ $? -ne 0 ]; then
>> +            echo "Failed to copy rootfs"
>> +            return 1
>> +        fi
>> +
>> +        return 0
>> +
>> +    ) 200>/var/lock/subsys/lxc
>> +
>> +    return $?
>> +}
>> +
>> +copy_configuration()
>> +{
>> +    path=$1
>> +    rootfs=$2
>> +    name=$3
>> +    arch=$4
>> +    release=$5
>> +
>> +    if [ $arch = "i386" ]; then
>> +        arch="i686"
>> +    fi
>> +
>> +    ttydir=""
>> +    if [ -f $rootfs/etc/init/container-detect.conf ]; then
>> +        ttydir=" lxc"
>> +    fi
>> +
>> +    # if there is exactly one veth network entry, make sure it has an
>> +    # associated hwaddr.
>> +    nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
>> +    if [ $nics -eq 1 ]; then
>> +        grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
>> +lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
>> +EOF
>> +    fi
>> +
>> +    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
>> +    cat <<EOF >> $path/config
>> +lxc.utsname = $name
>> +
>> +lxc.devttydir =$ttydir
>> +lxc.tty = 4
>> +lxc.pts = 1024
>> +lxc.mount  = $path/fstab
>> +lxc.arch = $arch
>> +lxc.cap.drop = sys_module mac_admin mac_override
>> +lxc.pivotdir = lxc_putold
>> +
>> +# When using LXC with apparmor, uncomment the next line to run unconfined:
>> +#lxc.aa_profile = unconfined
>> +
>> +lxc.cgroup.devices.deny = a
>> +# Allow any mknod (but not using the node)
>> +lxc.cgroup.devices.allow = c *:* m
>> +lxc.cgroup.devices.allow = b *:* m
>> +# /dev/null and zero
>> +lxc.cgroup.devices.allow = c 1:3 rwm
>> +lxc.cgroup.devices.allow = c 1:5 rwm
>> +# consoles
>> +lxc.cgroup.devices.allow = c 5:1 rwm
>> +lxc.cgroup.devices.allow = c 5:0 rwm
>> +#lxc.cgroup.devices.allow = c 4:0 rwm
>> +#lxc.cgroup.devices.allow = c 4:1 rwm
>> +# /dev/{,u}random
>> +lxc.cgroup.devices.allow = c 1:9 rwm
>> +lxc.cgroup.devices.allow = c 1:8 rwm
>> +lxc.cgroup.devices.allow = c 136:* rwm
>> +lxc.cgroup.devices.allow = c 5:2 rwm
>> +# rtc
>> +lxc.cgroup.devices.allow = c 254:0 rwm
>> +#fuse
>> +lxc.cgroup.devices.allow = c 10:229 rwm
>> +#tun
>> +lxc.cgroup.devices.allow = c 10:200 rwm
>> +#full
>> +lxc.cgroup.devices.allow = c 1:7 rwm
>> +#hpet
>> +lxc.cgroup.devices.allow = c 10:228 rwm
>> +#kvm
>> +lxc.cgroup.devices.allow = c 10:232 rwm
>> +EOF
>> +
>> +    cat <<EOF > $path/fstab
>> +proc            proc         proc    nodev,noexec,nosuid 0 0
>> +sysfs           sys          sysfs defaults  0 0
>> +EOF
>> +
>> +    if [ $? -ne 0 ]; then
>> +        echo "Failed to add configuration"
>> +        return 1
>> +    fi
>> +
>> +    return 0
>> +}
>> +
>> +trim()
>> +{
>> +    rootfs=$1
>> +    release=$2
>> +
>> +    # provide the lxc service
>> +    cat <<EOF > $rootfs/etc/init/lxc.conf
>> +# fake some events needed for correct startup other services
>> +
>> +description     "Container Upstart"
>> +
>> +start on startup
>> +
>> +script
>> +        rm -rf /var/run/*.pid
>> +        rm -rf /var/run/network/*
>> +        /sbin/initctl emit stopped JOB=udevtrigger --no-wait
>> +        /sbin/initctl emit started JOB=udev --no-wait
>> +end script
>> +EOF
>> +
>> +    # fix buggus runlevel with sshd
>> +    cat <<EOF > $rootfs/etc/init/ssh.conf
>> +# ssh - OpenBSD Secure Shell server
>> +#
>> +# The OpenSSH server provides secure shell access to the system.
>> +
>> +description	"OpenSSH server"
>> +
>> +start on filesystem
>> +stop on runlevel [!2345]
>> +
>> +expect fork
>> +respawn
>> +respawn limit 10 5
>> +umask 022
>> +# replaces SSHD_OOM_ADJUST in /etc/default/ssh
>> +oom never
>> +
>> +pre-start script
>> +    test -x /usr/sbin/sshd || { stop; exit 0; }
>> +    test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
>> +    test -c /dev/null || { stop; exit 0; }
>> +
>> +    mkdir -p -m0755 /var/run/sshd
>> +end script
>> +
>> +# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
>> +# 'exec' line here instead
>> +exec /usr/sbin/sshd
>> +EOF
>> +
>> +    cat <<EOF > $rootfs/etc/init/console.conf
>> +# console - getty
>> +#
>> +# This service maintains a console on tty1 from the point the system is
>> +# started until it is shut down again.
>> +
>> +start on stopped rc RUNLEVEL=[2345]
>> +stop on runlevel [!2345]
>> +
>> +respawn
>> +exec /sbin/getty -8 38400 /dev/console
>> +EOF
>> +
>> +    cat <<EOF > $rootfs/lib/init/fstab
>> +# /lib/init/fstab: cleared out for bare-bones lxc
>> +EOF
>> +
>> +    # remove pointless services in a container
>> +    chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
>> +
>> +    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
>> +    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
>> +    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
>> +    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
>> +    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
>> +
>> +    # if this isn't lucid, then we need to twiddle the network upstart bits :(
>> +    if [ $release != "lucid" ]; then
>> +        sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
>> +    fi
>> +}
>> +
>> +post_process()
>> +{
>> +    rootfs=$1
>> +    release=$2
>> +    trim_container=$3
>> +
>> +    if [ $trim_container -eq 1 ]; then
>> +        trim $rootfs $release
>> +    elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> +        # Make sure we have a working resolv.conf
>> +        cresolvonf="${rootfs}/etc/resolv.conf"
>> +        mv $cresolvonf ${cresolvonf}.lxcbak
>> +        cat /etc/resolv.conf > ${cresolvonf}
>> +
>> +        # for lucid, if not trimming, then add the ubuntu-virt
>> +        # ppa and install lxcguest
>> +        if [ $release = "lucid" ]; then
>> +            chroot $rootfs apt-get update
>> +            chroot $rootfs apt-get install --force-yes -y python-software-properties
>> +            chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
>> +        fi
>> +
>> +        chroot $rootfs apt-get update
>> +        chroot $rootfs apt-get install --force-yes -y lxcguest
>> +
>> +        # Restore old resolv.conf
>> +        rm -f ${cresolvonf}
>> +        mv ${cresolvonf}.lxcbak ${cresolvonf}
>> +    fi
>> +
>> +    # If the container isn't running a native architecture, setup multiarch
>> +    if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
>> +        dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
>> +        if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
>> +            chroot $rootfs dpkg --add-architecture ${hostarch}
>> +        else
>> +            mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
>> +            echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
>> +        fi
>> +
>> +        # Save existing value of MIRROR and SECURITY_MIRROR
>> +        DEFAULT_MIRROR=$MIRROR
>> +        DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
>> +
>> +        # Write a new sources.list containing both native and multiarch entries
>> +        > ${rootfs}/etc/apt/sources.list
>> +        write_sourceslist $rootfs $arch "native"
>> +
>> +        MIRROR=$DEFAULT_MIRROR
>> +        SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
>> +        write_sourceslist $rootfs $hostarch "multiarch"
>> +
>> +        # Finally update the lists and install upstart using the host architecture
>> +        chroot $rootfs apt-get update
>> +        chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
>> +    fi
>> +
>> +    # rmdir /dev/shm for containers that have /run/shm
>> +    # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
>> +    # get bind mounted to the host's /run/shm.  So try to rmdir
>> +    # it, and in case that fails move it out of the way.
>> +    if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
>> +        mv $rootfs/dev/shm $rootfs/dev/shm.bak
>> +        ln -s /run/shm $rootfs/dev/shm
>> +    fi
>> +}
>> +
>> +do_bindhome()
>> +{
>> +    rootfs=$1
>> +    user=$2
>> +
>> +    # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
>> +    pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; }
>> +    echo $pwd >> $rootfs/etc/passwd
>> +
>> +    # make sure user's shell exists in the container
>> +    shell=`echo $pwd | cut -d: -f 7`
>> +    if [ ! -x $rootfs/$shell ]; then
>> +        echo "shell $shell for user $user was not found in the container."
>> +        pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1`
>> +        echo "Installing $pkg"
>> +        chroot $rootfs apt-get --force-yes -y install $pkg
>> +    fi
>> +
>> +    shad=`getent shadow $user`
>> +    echo "$shad" >> $rootfs/etc/shadow
>> +
>> +    # bind-mount the user's path into the container's /home
>> +    h=`getent passwd $user | cut -d: -f 6`
>> +    mkdir -p $rootfs/$h
>> +
>> +    # use relative path in container
>> +    h2=${h#/}
>> +    while [ ${h2:0:1} = "/" ]; do
>> +        h2=${h2#/}
>> +    done
>> +    echo "$h $h2 none bind 0 0" >> $path/fstab
>> +
>> +    # Make sure the group exists in container
>> +    grp=`echo $pwd | cut -d: -f 4`  # group number for $user
>> +    grpe=`getent group $grp` || return 0  # if host doesn't define grp, ignore in container
>> +    chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group
>> +}
>> +
>> +usage()
>> +{
>> +    cat <<EOF
>> +$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [--trim] [-d|--debug]
>> +   [-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
>> +release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
>> +trim: make a minimal (faster, but not upgrade-safe) container
>> +bindhome: bind <user>'s home into the container
>> +          The ubuntu user will not be created, and <user> will have
>> +          sudo access.
>> +arch: the container architecture (e.g. amd64): defaults to host arch
>> +auth-key: SSH Public key file to inject into container
>> +EOF
>> +    return 0
>> +}
>> +
>> +options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@")
>> +if [ $? -ne 0 ]; then
>> +    usage $(basename $0)
>> +    exit 1
>> +fi
>> +eval set -- "$options"
>> +
>> +release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
>> +if [ -f /etc/lsb-release ]; then
>> +    . /etc/lsb-release
>> +    if [ "$DISTRIB_ID" = "Ubuntu" ]; then
>> +        release=$DISTRIB_CODENAME
>> +    fi
>> +fi
>> +
>> +bindhome=
>> +arch=$(arch)
>> +
>> +# Code taken from debootstrap
>> +if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
>> +    arch=`/usr/bin/dpkg --print-architecture`
>> +elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
>> +    arch=`/usr/bin/udpkg --print-architecture`
>> +else
>> +    arch=$(arch)
>> +    if [ "$arch" = "i686" ]; then
>> +        arch="i386"
>> +    elif [ "$arch" = "x86_64" ]; then
>> +        arch="amd64"
>> +    elif [ "$arch" = "armv7l" ]; then
>> +        arch="armel"
>> +    fi
>> +fi
>> +
>> +debug=0
>> +trim_container=0
>> +hostarch=$arch
>> +flushcache=0
>> +while true
>> +do
>> +    case "$1" in
>> +    -h|--help)      usage $0 && exit 0;;
>> +    -p|--path)      path=$2; shift 2;;
>> +    -n|--name)      name=$2; shift 2;;
>> +    -F|--flush-cache) flushcache=1; shift 1;;
>> +    -r|--release)   release=$2; shift 2;;
>> +    -b|--bindhome)  bindhome=$2; shift 2;;
>> +    -a|--arch)      arch=$2; shift 2;;
>> +    -x|--trim)      trim_container=1; shift 1;;
>> +    -S|--auth-key)  auth_key=$2; shift 2;;
>> +    -d|--debug)     debug=1; shift 1;;
>> +    --)             shift 1; break ;;
>> +        *)              break ;;
>> +    esac
>> +done
>> +
>> +if [ $debug -eq 1 ]; then
>> +    set -x
>> +fi
>> +
>> +if [ -n "$bindhome" ]; then
>> +    pwd=`getent passwd $bindhome`
>> +    if [ $? -ne 0 ]; then
>> +        echo "Error: no password entry found for $bindhome"
>> +        exit 1
>> +    fi
>> +fi
>> +
>> +
>> +if [ "$arch" == "i686" ]; then
>> +    arch=i386
>> +fi
>> +
>> +if [ $hostarch = "i386" -a $arch = "amd64" ]; then
>> +    echo "can't create amd64 container on i386"
>> +    exit 1
>> +fi
>> +
>> +type debootstrap
>> +if [ $? -ne 0 ]; then
>> +    echo "'debootstrap' command is missing"
>> +    exit 1
>> +fi
>> +
>> +if [ -z "$path" ]; then
>> +    echo "'path' parameter is required"
>> +    exit 1
>> +fi
>> +
>> +if [ "$(id -u)" != "0" ]; then
>> +    echo "This script should be run as 'root'"
>> +    exit 1
>> +fi
>> +
>> +# detect rootfs
>> +config="$path/config"
>> +if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
>> +    rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
>> +else
>> +    rootfs=$path/rootfs
>> +fi
>> +
>> +install_ubuntu $rootfs $release $flushcache
>> +if [ $? -ne 0 ]; then
>> +    echo "failed to install ubuntu $release"
>> +    exit 1
>> +fi
>> +
>> +configure_ubuntu $rootfs $name $release
>> +if [ $? -ne 0 ]; then
>> +    echo "failed to configure ubuntu $release for a container"
>> +    exit 1
>> +fi
>> +
>> +copy_configuration $path $rootfs $name $arch $release
>> +if [ $? -ne 0 ]; then
>> +    echo "failed write configuration file"
>> +    exit 1
>> +fi
>> +
>> +post_process $rootfs $release $trim_container
>> +
>> +if [ -n "$bindhome" ]; then
>> +    do_bindhome $rootfs $bindhome
>> +    finalize_user $bindhome
>> +else
>> +    finalize_user ubuntu
>> +fi
>> +
>> +echo ""
>> +echo "##"
>> +if [ -n "$bindhome" ]; then
>> +	echo "# Log in as user $bindhome"
>> +else
>> +	echo "# The default user is 'ubuntu' with password 'ubuntu'!"
>> +	echo "# Use the 'sudo' command to run tasks as root in the container."
>> +fi
>> +echo "##"
>> +echo ""
>> diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in
>> deleted file mode 100644
>> index ce1e065..0000000
>> --- a/templates/lxc-ubuntu.in
>> +++ /dev/null
>> @@ -1,729 +0,0 @@
>> -#!/bin/bash
>> -
>> -#
>> -# template script for generating ubuntu container for LXC
>> -#
>> -# This script consolidates and extends the existing lxc ubuntu scripts
>> -#
>> -
>> -# Copyright ? 2011 Serge Hallyn <serge.hallyn at canonical.com>
>> -# Copyright ? 2010 Wilhelm Meier
>> -# Author: Wilhelm Meier <wilhelm.meier at fh-kl.de>
>> -#
>> -# This program is free software; you can redistribute it and/or modify
>> -# it under the terms of the GNU General Public License version 2, as
>> -# published by the Free Software Foundation.
>> -
>> -# This program is distributed in the hope that it will be useful,
>> -# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> -# GNU General Public License for more details.
>> -
>> -# You should have received a copy of the GNU General Public License along
>> -# with this program; if not, write to the Free Software Foundation, Inc.,
>> -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> -#
>> -
>> -set -e
>> -
>> -if [ -r /etc/default/lxc ]; then
>> -    . /etc/default/lxc
>> -fi
>> -
>> -configure_ubuntu()
>> -{
>> -    rootfs=$1
>> -    hostname=$2
>> -    release=$3
>> -
>> -   # configure the network using the dhcp
>> -    cat <<EOF > $rootfs/etc/network/interfaces
>> -# This file describes the network interfaces available on your system
>> -# and how to activate them. For more information, see interfaces(5).
>> -
>> -# The loopback network interface
>> -auto lo
>> -iface lo inet loopback
>> -
>> -auto eth0
>> -iface eth0 inet dhcp
>> -EOF
>> -
>> -    # set the hostname
>> -    cat <<EOF > $rootfs/etc/hostname
>> -$hostname
>> -EOF
>> -    # set minimal hosts
>> -    cat <<EOF > $rootfs/etc/hosts
>> -127.0.0.1   localhost
>> -127.0.1.1   $hostname
>> -
>> -# The following lines are desirable for IPv6 capable hosts
>> -::1     ip6-localhost ip6-loopback
>> -fe00::0 ip6-localnet
>> -ff00::0 ip6-mcastprefix
>> -ff02::1 ip6-allnodes
>> -ff02::2 ip6-allrouters
>> -EOF
>> -
>> -    if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> -        # suppress log level output for udev
>> -        sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
>> -
>> -        # remove jobs for consoles 5 and 6 since we only create 4 consoles in
>> -        # this template
>> -        rm -f $rootfs/etc/init/tty{5,6}.conf
>> -    fi
>> -
>> -    if [ -z "$bindhome" ]; then
>> -        chroot $rootfs useradd --create-home -s /bin/bash ubuntu
>> -        echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
>> -    fi
>> -
>> -    # make sure we have the current locale defined in the container
>> -    if [ -z "$LANG" ]; then
>> -        chroot $rootfs locale-gen en_US.UTF-8
>> -        chroot $rootfs update-locale LANG=en_US.UTF-8
>> -    else
>> -        chroot $rootfs locale-gen $LANG
>> -        chroot $rootfs update-locale LANG=$LANG
>> -    fi
>> -
>> -    return 0
>> -}
>> -
>> -# finish setting up the user in the container by injecting ssh key and
>> -# adding sudo group membership.
>> -# passed-in user is either 'ubuntu' or the user to bind in from host.
>> -finalize_user()
>> -{
>> -    user=$1
>> -
>> -    sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
>> -
>> -    if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
>> -        groups="sudo"
>> -    else
>> -        groups="sudo admin"
>> -    fi
>> -
>> -    for group in $groups; do
>> -        chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
>> -        chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
>> -    done
>> -
>> -    if [ -n "$auth_key" -a -f "$auth_key" ]; then
>> -	u_path="/home/${user}/.ssh"
>> -	root_u_path="$rootfs/$u_path"
>> -	mkdir -p $root_u_path
>> -	cp $auth_key "$root_u_path/authorized_keys"
>> -	chroot $rootfs chown -R ${user}: "$u_path"
>> -
>> -	echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
>> -    fi
>> -    return 0
>> -}
>> -
>> -write_sourceslist()
>> -{
>> -    # $1 => path to the rootfs
>> -    # $2 => architecture we want to add
>> -    # $3 => whether to use the multi-arch syntax or not
>> -
>> -    case $2 in
>> -      amd64|i386)
>> -            MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
>> -            SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
>> -            ;;
>> -      *)
>> -            MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> -            SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> -            ;;
>> -    esac
>> -    if [ -n "$3" ]; then
>> -        cat >> "$1/etc/apt/sources.list" << EOF
>> -deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
>> -deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
>> -deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> -EOF
>> -    else
>> -        cat >> "$1/etc/apt/sources.list" << EOF
>> -deb $MIRROR ${release} main restricted universe multiverse
>> -deb $MIRROR ${release}-updates main restricted universe multiverse
>> -deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> -EOF
>> -    fi
>> -}
>> -
>> -cleanup()
>> -{
>> -    rm -rf $cache/partial-$arch
>> -    rm -rf $cache/rootfs-$arch
>> -}
>> -
>> -suggest_flush()
>> -{
>> -    echo "Container upgrade failed.  The container cache may be out of date,"
>> -    echo "in which case flushing the case (see -F in the hep output) may help."
>> -}
>> -
>> -download_ubuntu()
>> -{
>> -    cache=$1
>> -    arch=$2
>> -    release=$3
>> -
>> -    packages=vim,ssh
>> -
>> -    # Try to guess a list of langpacks to install
>> -    langpacks="language-pack-en"
>> -
>> -    if which dpkg >/dev/null 2>&1; then
>> -        langpacks=`(echo $LANGPACK_LIST &&
>> -                    dpkg -l | grep -E "^ii  language-pack-[a-z]* " |
>> -                        cut -d ' ' -f3) | sort -u`
>> -    fi
>> -    packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
>> -
>> -
>> -    echo "installing packages: $packages"
>> -
>> -    trap cleanup EXIT SIGHUP SIGINT SIGTERM
>> -    # check the mini ubuntu was not already downloaded
>> -    mkdir -p "$cache/partial-$arch"
>> -    if [ $? -ne 0 ]; then
>> -        echo "Failed to create '$cache/partial-$arch' directory"
>> -        return 1
>> -    fi
>> -
>> -    # download a mini ubuntu into a cache
>> -    echo "Downloading ubuntu $release minimal ..."
>> -    if [ -n "$(which qemu-debootstrap)" ]; then
>> -        qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> -    else
>> -        debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> -    fi
>> -
>> -    if [ $? -ne 0 ]; then
>> -        echo "Failed to download the rootfs, aborting."
>> -            return 1
>> -    fi
>> -
>> -    # Serge isn't sure whether we should avoid doing this when
>> -    # $release == `distro-info -d`
>> -    echo "Installing updates"
>> -    > $cache/partial-$arch/etc/apt/sources.list
>> -    write_sourceslist $cache/partial-$arch/ $arch
>> -
>> -    chroot "$1/partial-${arch}" apt-get update
>> -    if [ $? -ne 0 ]; then
>> -        echo "Failed to update the apt cache"
>> -        return 1
>> -    fi
>> -    cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
>> -#!/bin/sh
>> -exit 101
>> -EOF
>> -    chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> -
>> -    lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; }
>> -    rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> -
>> -    chroot "$1/partial-${arch}" apt-get clean
>> -
>> -    mv "$1/partial-$arch" "$1/rootfs-$arch"
>> -    trap EXIT
>> -    trap SIGINT
>> -    trap SIGTERM
>> -    trap SIGHUP
>> -    echo "Download complete"
>> -    return 0
>> -}
>> -
>> -copy_ubuntu()
>> -{
>> -    cache=$1
>> -    arch=$2
>> -    rootfs=$3
>> -
>> -    # make a local copy of the miniubuntu
>> -    echo "Copying rootfs to $rootfs ..."
>> -    mkdir -p $rootfs
>> -    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
>> -    return 0
>> -}
>> -
>> -install_ubuntu()
>> -{
>> -    rootfs=$1
>> -    release=$2
>> -    flushcache=$3
>> -    cache="/var/cache/lxc/$release"
>> -    mkdir -p /var/lock/subsys/
>> -
>> -    (
>> -        flock -x 200
>> -        if [ $? -ne 0 ]; then
>> -            echo "Cache repository is busy."
>> -            return 1
>> -        fi
>> -
>> -
>> -        if [ $flushcache -eq 1 ]; then
>> -            echo "Flushing cache..."
>> -            rm -rf "$cache/partial-$arch"
>> -            rm -rf "$cache/rootfs-$arch"
>> -        fi
>> -
>> -        echo "Checking cache download in $cache/rootfs-$arch ... "
>> -        if [ ! -e "$cache/rootfs-$arch" ]; then
>> -            download_ubuntu $cache $arch $release
>> -            if [ $? -ne 0 ]; then
>> -                echo "Failed to download 'ubuntu $release base'"
>> -                return 1
>> -            fi
>> -        fi
>> -
>> -        echo "Copy $cache/rootfs-$arch to $rootfs ... "
>> -        copy_ubuntu $cache $arch $rootfs
>> -        if [ $? -ne 0 ]; then
>> -            echo "Failed to copy rootfs"
>> -            return 1
>> -        fi
>> -
>> -        return 0
>> -
>> -    ) 200>/var/lock/subsys/lxc
>> -
>> -    return $?
>> -}
>> -
>> -copy_configuration()
>> -{
>> -    path=$1
>> -    rootfs=$2
>> -    name=$3
>> -    arch=$4
>> -    release=$5
>> -
>> -    if [ $arch = "i386" ]; then
>> -        arch="i686"
>> -    fi
>> -
>> -    ttydir=""
>> -    if [ -f $rootfs/etc/init/container-detect.conf ]; then
>> -        ttydir=" lxc"
>> -    fi
>> -
>> -    # if there is exactly one veth network entry, make sure it has an
>> -    # associated hwaddr.
>> -    nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
>> -    if [ $nics -eq 1 ]; then
>> -        grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
>> -lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
>> -EOF
>> -    fi
>> -
>> -    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
>> -    cat <<EOF >> $path/config
>> -lxc.utsname = $name
>> -
>> -lxc.devttydir =$ttydir
>> -lxc.tty = 4
>> -lxc.pts = 1024
>> -lxc.mount  = $path/fstab
>> -lxc.arch = $arch
>> -lxc.cap.drop = sys_module mac_admin mac_override
>> -lxc.pivotdir = lxc_putold
>> -
>> -# When using LXC with apparmor, uncomment the next line to run unconfined:
>> -#lxc.aa_profile = unconfined
>> -
>> -lxc.cgroup.devices.deny = a
>> -# Allow any mknod (but not using the node)
>> -lxc.cgroup.devices.allow = c *:* m
>> -lxc.cgroup.devices.allow = b *:* m
>> -# /dev/null and zero
>> -lxc.cgroup.devices.allow = c 1:3 rwm
>> -lxc.cgroup.devices.allow = c 1:5 rwm
>> -# consoles
>> -lxc.cgroup.devices.allow = c 5:1 rwm
>> -lxc.cgroup.devices.allow = c 5:0 rwm
>> -#lxc.cgroup.devices.allow = c 4:0 rwm
>> -#lxc.cgroup.devices.allow = c 4:1 rwm
>> -# /dev/{,u}random
>> -lxc.cgroup.devices.allow = c 1:9 rwm
>> -lxc.cgroup.devices.allow = c 1:8 rwm
>> -lxc.cgroup.devices.allow = c 136:* rwm
>> -lxc.cgroup.devices.allow = c 5:2 rwm
>> -# rtc
>> -lxc.cgroup.devices.allow = c 254:0 rwm
>> -#fuse
>> -lxc.cgroup.devices.allow = c 10:229 rwm
>> -#tun
>> -lxc.cgroup.devices.allow = c 10:200 rwm
>> -#full
>> -lxc.cgroup.devices.allow = c 1:7 rwm
>> -#hpet
>> -lxc.cgroup.devices.allow = c 10:228 rwm
>> -#kvm
>> -lxc.cgroup.devices.allow = c 10:232 rwm
>> -EOF
>> -
>> -    cat <<EOF > $path/fstab
>> -proc            proc         proc    nodev,noexec,nosuid 0 0
>> -sysfs           sys          sysfs defaults  0 0
>> -EOF
>> -
>> -    if [ $? -ne 0 ]; then
>> -        echo "Failed to add configuration"
>> -        return 1
>> -    fi
>> -
>> -    return 0
>> -}
>> -
>> -trim()
>> -{
>> -    rootfs=$1
>> -    release=$2
>> -
>> -    # provide the lxc service
>> -    cat <<EOF > $rootfs/etc/init/lxc.conf
>> -# fake some events needed for correct startup other services
>> -
>> -description     "Container Upstart"
>> -
>> -start on startup
>> -
>> -script
>> -        rm -rf /var/run/*.pid
>> -        rm -rf /var/run/network/*
>> -        /sbin/initctl emit stopped JOB=udevtrigger --no-wait
>> -        /sbin/initctl emit started JOB=udev --no-wait
>> -end script
>> -EOF
>> -
>> -    # fix buggus runlevel with sshd
>> -    cat <<EOF > $rootfs/etc/init/ssh.conf
>> -# ssh - OpenBSD Secure Shell server
>> -#
>> -# The OpenSSH server provides secure shell access to the system.
>> -
>> -description	"OpenSSH server"
>> -
>> -start on filesystem
>> -stop on runlevel [!2345]
>> -
>> -expect fork
>> -respawn
>> -respawn limit 10 5
>> -umask 022
>> -# replaces SSHD_OOM_ADJUST in /etc/default/ssh
>> -oom never
>> -
>> -pre-start script
>> -    test -x /usr/sbin/sshd || { stop; exit 0; }
>> -    test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
>> -    test -c /dev/null || { stop; exit 0; }
>> -
>> -    mkdir -p -m0755 /var/run/sshd
>> -end script
>> -
>> -# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
>> -# 'exec' line here instead
>> -exec /usr/sbin/sshd
>> -EOF
>> -
>> -    cat <<EOF > $rootfs/etc/init/console.conf
>> -# console - getty
>> -#
>> -# This service maintains a console on tty1 from the point the system is
>> -# started until it is shut down again.
>> -
>> -start on stopped rc RUNLEVEL=[2345]
>> -stop on runlevel [!2345]
>> -
>> -respawn
>> -exec /sbin/getty -8 38400 /dev/console
>> -EOF
>> -
>> -    cat <<EOF > $rootfs/lib/init/fstab
>> -# /lib/init/fstab: cleared out for bare-bones lxc
>> -EOF
>> -
>> -    # remove pointless services in a container
>> -    chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
>> -
>> -    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
>> -    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
>> -    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
>> -    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
>> -    chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
>> -
>> -    # if this isn't lucid, then we need to twiddle the network upstart bits :(
>> -    if [ $release != "lucid" ]; then
>> -        sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
>> -    fi
>> -}
>> -
>> -post_process()
>> -{
>> -    rootfs=$1
>> -    release=$2
>> -    trim_container=$3
>> -
>> -    if [ $trim_container -eq 1 ]; then
>> -        trim $rootfs $release
>> -    elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> -        # Make sure we have a working resolv.conf
>> -        cresolvonf="${rootfs}/etc/resolv.conf"
>> -        mv $cresolvonf ${cresolvonf}.lxcbak
>> -        cat /etc/resolv.conf > ${cresolvonf}
>> -
>> -        # for lucid, if not trimming, then add the ubuntu-virt
>> -        # ppa and install lxcguest
>> -        if [ $release = "lucid" ]; then
>> -            chroot $rootfs apt-get update
>> -            chroot $rootfs apt-get install --force-yes -y python-software-properties
>> -            chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
>> -        fi
>> -
>> -        chroot $rootfs apt-get update
>> -        chroot $rootfs apt-get install --force-yes -y lxcguest
>> -
>> -        # Restore old resolv.conf
>> -        rm -f ${cresolvonf}
>> -        mv ${cresolvonf}.lxcbak ${cresolvonf}
>> -    fi
>> -
>> -    # If the container isn't running a native architecture, setup multiarch
>> -    if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
>> -        dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
>> -        if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
>> -            chroot $rootfs dpkg --add-architecture ${hostarch}
>> -        else
>> -            mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
>> -            echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
>> -        fi
>> -
>> -        # Save existing value of MIRROR and SECURITY_MIRROR
>> -        DEFAULT_MIRROR=$MIRROR
>> -        DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
>> -
>> -        # Write a new sources.list containing both native and multiarch entries
>> -        > ${rootfs}/etc/apt/sources.list
>> -        write_sourceslist $rootfs $arch "native"
>> -
>> -        MIRROR=$DEFAULT_MIRROR
>> -        SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
>> -        write_sourceslist $rootfs $hostarch "multiarch"
>> -
>> -        # Finally update the lists and install upstart using the host architecture
>> -        chroot $rootfs apt-get update
>> -        chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
>> -    fi
>> -
>> -    # rmdir /dev/shm for containers that have /run/shm
>> -    # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
>> -    # get bind mounted to the host's /run/shm.  So try to rmdir
>> -    # it, and in case that fails move it out of the way.
>> -    if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
>> -        mv $rootfs/dev/shm $rootfs/dev/shm.bak
>> -        ln -s /run/shm $rootfs/dev/shm
>> -    fi
>> -}
>> -
>> -do_bindhome()
>> -{
>> -    rootfs=$1
>> -    user=$2
>> -
>> -    # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
>> -    pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; }
>> -    echo $pwd >> $rootfs/etc/passwd
>> -
>> -    # make sure user's shell exists in the container
>> -    shell=`echo $pwd | cut -d: -f 7`
>> -    if [ ! -x $rootfs/$shell ]; then
>> -        echo "shell $shell for user $user was not found in the container."
>> -        pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1`
>> -        echo "Installing $pkg"
>> -        chroot $rootfs apt-get --force-yes -y install $pkg
>> -    fi
>> -
>> -    shad=`getent shadow $user`
>> -    echo "$shad" >> $rootfs/etc/shadow
>> -
>> -    # bind-mount the user's path into the container's /home
>> -    h=`getent passwd $user | cut -d: -f 6`
>> -    mkdir -p $rootfs/$h
>> -
>> -    # use relative path in container
>> -    h2=${h#/}
>> -    while [ ${h2:0:1} = "/" ]; do
>> -        h2=${h2#/}
>> -    done
>> -    echo "$h $h2 none bind 0 0" >> $path/fstab
>> -
>> -    # Make sure the group exists in container
>> -    grp=`echo $pwd | cut -d: -f 4`  # group number for $user
>> -    grpe=`getent group $grp` || return 0  # if host doesn't define grp, ignore in container
>> -    chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group
>> -}
>> -
>> -usage()
>> -{
>> -    cat <<EOF
>> -$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [--trim] [-d|--debug]
>> -   [-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
>> -release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
>> -trim: make a minimal (faster, but not upgrade-safe) container
>> -bindhome: bind <user>'s home into the container
>> -          The ubuntu user will not be created, and <user> will have
>> -          sudo access.
>> -arch: the container architecture (e.g. amd64): defaults to host arch
>> -auth-key: SSH Public key file to inject into container
>> -EOF
>> -    return 0
>> -}
>> -
>> -options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@")
>> -if [ $? -ne 0 ]; then
>> -    usage $(basename $0)
>> -    exit 1
>> -fi
>> -eval set -- "$options"
>> -
>> -release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
>> -if [ -f /etc/lsb-release ]; then
>> -    . /etc/lsb-release
>> -    if [ "$DISTRIB_ID" = "Ubuntu" ]; then
>> -        release=$DISTRIB_CODENAME
>> -    fi
>> -fi
>> -
>> -bindhome=
>> -arch=$(arch)
>> -
>> -# Code taken from debootstrap
>> -if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
>> -    arch=`/usr/bin/dpkg --print-architecture`
>> -elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
>> -    arch=`/usr/bin/udpkg --print-architecture`
>> -else
>> -    arch=$(arch)
>> -    if [ "$arch" = "i686" ]; then
>> -        arch="i386"
>> -    elif [ "$arch" = "x86_64" ]; then
>> -        arch="amd64"
>> -    elif [ "$arch" = "armv7l" ]; then
>> -        arch="armel"
>> -    fi
>> -fi
>> -
>> -debug=0
>> -trim_container=0
>> -hostarch=$arch
>> -flushcache=0
>> -while true
>> -do
>> -    case "$1" in
>> -    -h|--help)      usage $0 && exit 0;;
>> -    -p|--path)      path=$2; shift 2;;
>> -    -n|--name)      name=$2; shift 2;;
>> -    -F|--flush-cache) flushcache=1; shift 1;;
>> -    -r|--release)   release=$2; shift 2;;
>> -    -b|--bindhome)  bindhome=$2; shift 2;;
>> -    -a|--arch)      arch=$2; shift 2;;
>> -    -x|--trim)      trim_container=1; shift 1;;
>> -    -S|--auth-key)  auth_key=$2; shift 2;;
>> -    -d|--debug)     debug=1; shift 1;;
>> -    --)             shift 1; break ;;
>> -        *)              break ;;
>> -    esac
>> -done
>> -
>> -if [ $debug -eq 1 ]; then
>> -    set -x
>> -fi
>> -
>> -if [ -n "$bindhome" ]; then
>> -    pwd=`getent passwd $bindhome`
>> -    if [ $? -ne 0 ]; then
>> -        echo "Error: no password entry found for $bindhome"
>> -        exit 1
>> -    fi
>> -fi
>> -
>> -
>> -if [ "$arch" == "i686" ]; then
>> -    arch=i386
>> -fi
>> -
>> -if [ $hostarch = "i386" -a $arch = "amd64" ]; then
>> -    echo "can't create amd64 container on i386"
>> -    exit 1
>> -fi
>> -
>> -type debootstrap
>> -if [ $? -ne 0 ]; then
>> -    echo "'debootstrap' command is missing"
>> -    exit 1
>> -fi
>> -
>> -if [ -z "$path" ]; then
>> -    echo "'path' parameter is required"
>> -    exit 1
>> -fi
>> -
>> -if [ "$(id -u)" != "0" ]; then
>> -    echo "This script should be run as 'root'"
>> -    exit 1
>> -fi
>> -
>> -# detect rootfs
>> -config="$path/config"
>> -if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
>> -    rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
>> -else
>> -    rootfs=$path/rootfs
>> -fi
>> -
>> -install_ubuntu $rootfs $release $flushcache
>> -if [ $? -ne 0 ]; then
>> -    echo "failed to install ubuntu $release"
>> -    exit 1
>> -fi
>> -
>> -configure_ubuntu $rootfs $name $release
>> -if [ $? -ne 0 ]; then
>> -    echo "failed to configure ubuntu $release for a container"
>> -    exit 1
>> -fi
>> -
>> -copy_configuration $path $rootfs $name $arch $release
>> -if [ $? -ne 0 ]; then
>> -    echo "failed write configuration file"
>> -    exit 1
>> -fi
>> -
>> -post_process $rootfs $release $trim_container
>> -
>> -if [ -n "$bindhome" ]; then
>> -    do_bindhome $rootfs $bindhome
>> -    finalize_user $bindhome
>> -else
>> -    finalize_user ubuntu
>> -fi
>> -
>> -echo ""
>> -echo "##"
>> -if [ -n "$bindhome" ]; then
>> -	echo "# Log in as user $bindhome"
>> -else
>> -	echo "# The default user is 'ubuntu' with password 'ubuntu'!"
>> -	echo "# Use the 'sudo' command to run tasks as root in the container."
>> -fi
>> -echo "##"
>> -echo ""
>> -- 
>> 1.8.0
>>
>>
> 
>> ------------------------------------------------------------------------------
>> Keep yourself connected to Go Parallel: 
>> INSIGHTS What's next for parallel hardware, programming and related areas?
>> Interviews and blogs by thought leaders keep you ahead of the curve.
>> http://goparallel.sourceforge.net
> 
>> _______________________________________________
>> Lxc-devel mailing list
>> Lxc-devel at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/lxc-devel
> 


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121129/ed651efe/attachment.pgp>


More information about the lxc-devel mailing list