[lxc-devel] [PATCH 1/4] lxc-ubuntu: Don't hardcode path to cache

Serge Hallyn serge.hallyn at canonical.com
Thu Dec 6 05:05:32 UTC 2012


Quoting Stéphane Graber (stgraber at ubuntu.com):
> Use LOCALSTATEDIR to generate the path to the cache.
> 
> Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>

> ---
>  configure.ac            |   1 +
>  templates/lxc-ubuntu    | 729 ------------------------------------------------
>  templates/lxc-ubuntu.in | 729 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 730 insertions(+), 729 deletions(-)
>  delete mode 100644 templates/lxc-ubuntu
>  create mode 100644 templates/lxc-ubuntu.in
> 
> diff --git a/configure.ac b/configure.ac
> index 626d202..893e179 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -245,6 +245,7 @@ AC_CONFIG_FILES([
>  	templates/Makefile
>  	templates/lxc-lenny
>  	templates/lxc-debian
> +	templates/lxc-ubuntu

That didn't last long :)

>  	templates/lxc-ubuntu-cloud
>  	templates/lxc-opensuse
>  	templates/lxc-busybox
> diff --git a/templates/lxc-ubuntu b/templates/lxc-ubuntu
> deleted file mode 100644
> index 4ccb015..0000000
> --- a/templates/lxc-ubuntu
> +++ /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 $langpacks &&
> -                    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 -Ha $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
> new file mode 100644
> index 0000000..19de991
> --- /dev/null
> +++ b/templates/lxc-ubuntu.in
> @@ -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 $langpacks &&
> +                    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 -Ha $cache/rootfs-$arch/ $rootfs/ || return 1
> +    return 0
> +}
> +
> +install_ubuntu()
> +{
> +    rootfs=$1
> +    release=$2
> +    flushcache=$3
> +    cache="@LOCALSTATEDIR@/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
> 
> 

> ------------------------------------------------------------------------------
> LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial
> Remotely access PCs and mobile devices and provide instant support
> Improve your efficiency, and focus on delivering more value-add services
> Discover what IT Professionals Know. Rescue delivers
> http://p.sf.net/sfu/logmein_12329d2d

> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel





More information about the lxc-devel mailing list