* /usr/lib/lxc/templates of lxc 0.8.0~rc1-4ubuntu37 on Ubuntu 12.10 (beta) vendor
authormitty <mitty@7d2118f6-f56c-43e7-95a2-4bb3031d96e7>
Tue, 16 Oct 2012 05:35:18 +0000 (05:35 +0000)
committermitty <mitty@7d2118f6-f56c-43e7-95a2-4bb3031d96e7>
Tue, 16 Oct 2012 05:35:18 +0000 (05:35 +0000)
git-svn-id: https://lab.mitty.jp/svn/lab/vendor@175 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

lxc/0.8.0~rc1-4ubuntu37/templates/lxc-altlinux [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-archlinux [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-busybox [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-debian [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-fedora [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-opensuse [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-sshd [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu [new file with mode: 0755]
lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu-cloud [new file with mode: 0755]

diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-altlinux b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-altlinux
new file mode 100755 (executable)
index 0000000..90506e6
--- /dev/null
@@ -0,0 +1,460 @@
+#!/bin/bash
+
+#
+# template script for generating altlinux container for LXC
+#
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Alexey Shabalin <shaba@altlinux.org>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#Configurations
+arch=$(arch)
+cache_base=/var/cache/lxc/altlinux/$arch
+default_path=${localstatedir}/lib/lxc
+default_profile=default
+profile_dir=/etc/lxc/profiles
+root_password=rooter
+lxc_network_type=veth
+lxc_network_link=virbr0
+
+# is this altlinux?
+[ -f /etc/altlinux-release ] && is_altlinux=true
+
+configure_altlinux()
+{
+
+    # disable selinux in altlinux
+    mkdir -p $rootfs_path/selinux
+    echo 0 > $rootfs_path/selinux/enforce
+
+    mkdir -p ${rootfs_path}/etc/net/ifaces/veth0
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/options
+BOOTPROTO=${BOOTPROTO}
+ONBOOT=yes
+NM_CONTROLLED=no
+TYPE=eth
+EOF
+
+if [ ${BOOTPROTO} != "dhcp" ]; then
+    # ip address
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/ipv4address
+${ipv4}
+EOF
+
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/ipv4route
+${gw}
+EOF
+
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/resolv.conf
+nameserver ${dns}
+EOF
+
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/ipv6address
+${ipv6}
+EOF
+
+    cat <<EOF > ${rootfs_path}/etc/net/ifaces/veth0/ipv6route
+${gw6}
+EOF
+
+fi
+
+    # set the hostname
+    cat <<EOF > ${rootfs_path}/etc/sysconfig/network
+NETWORKING=yes
+CONFMETHOD=etcnet
+HOSTNAME=${UTSNAME}
+RESOLV_MODS=yes
+EOF
+
+    # set minimal hosts
+    cat <<EOF > $rootfs_path/etc/hosts
+127.0.0.1 localhost.localdomain localhost $name
+EOF
+    # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd.
+#    sed -i 's/^.*loginuid.so.*$/\#&/' ${rootfs_path}/etc/pam.d/common-login
+
+    # Allow root to login at virsh console
+    echo "pts/0" >> ${rootfs_path}/etc/securetty
+    echo "console" >> ${rootfs_path}/etc/securetty
+
+    chroot ${rootfs_path} chkconfig network on
+    chroot ${rootfs_path} chkconfig syslogd on
+    chroot ${rootfs_path} chkconfig random on
+    chroot ${rootfs_path} chkconfig rawdevices off
+    chroot ${rootfs_path} chkconfig fbsetfont off
+#    chroot ${rootfs_path} chkconfig keytable off
+
+    subst 's/^\([3-9]\+:[0-9]\+:respawn:\/sbin\/mingetty.*\)/#\1/' ${rootfs_path}/etc/inittab
+    echo "c1:2345:respawn:/sbin/mingetty --noclear console" >>  ${rootfs_path}/etc/inittab
+    subst 's,\/dev\/tty12,/var/log/syslog/console,' ${rootfs_path}/etc/syslog.conf
+
+#   touch file for fastboot
+    touch ${rootfs_path}/fastboot
+    chattr +i ${rootfs_path}/fastboot
+
+    dev_path="${rootfs_path}/dev"
+    rm -rf ${dev_path}
+    mkdir -p ${dev_path}
+    mknod -m 666 ${dev_path}/null c 1 3
+    mknod -m 666 ${dev_path}/zero c 1 5
+    mknod -m 644 ${dev_path}/random c 1 8
+    mknod -m 644 ${dev_path}/urandom c 1 9
+    mkdir -m 755 ${dev_path}/pts
+    mkdir -m 1777 ${dev_path}/shm
+    mknod -m 666 ${dev_path}/tty c 5 0
+    chown root:tty ${dev_path}/tty
+    mknod -m 600 ${dev_path}/tty0 c 4 0
+    mknod -m 600 ${dev_path}/tty1 c 4 1
+    mknod -m 600 ${dev_path}/tty2 c 4 2
+    mknod -m 600 ${dev_path}/tty3 c 4 3
+    mknod -m 600 ${dev_path}/tty4 c 4 4
+    mknod -m 600 ${dev_path}/console c 5 1
+    mknod -m 666 ${dev_path}/full c 1 7
+    mknod -m 600 ${dev_path}/initctl p
+    mknod -m 666 ${dev_path}/ptmx c 5 2
+    chown root:tty ${dev_path}/ptmx
+    ln -s /proc/self/fd ${dev_path}/fd
+    ln -s /proc/kcore ${dev_path}/core
+    mkdir -m 755 ${dev_path}/mapper
+    mknod -m 600 ${dev_path}/mapper/control c 10 236
+    mkdir -m 755 ${dev_path}/net
+    mknod -m 666 ${dev_path}/net/tun c 10 200
+
+    echo "setting root passwd to $root_password"
+    echo "root:$root_password" | chroot $rootfs_path chpasswd
+
+    return 0
+}
+
+download_altlinux()
+{
+
+    # check the mini altlinux was not already downloaded
+    INSTALL_ROOT=$cache/partial
+    mkdir -p $INSTALL_ROOT
+    if [ $? -ne 0 ]; then
+       echo "Failed to create '$INSTALL_ROOT' directory"
+       return 1
+    fi
+
+    # download a mini altlinux into a cache
+    echo "Downloading altlinux minimal ..."
+    APT_GET="apt-get -o RPM::RootDir=$INSTALL_ROOT -y"
+    PKG_LIST="$(grep -hs '^[^#]' "$profile_dir/$profile")"
+#    PKG_LIST="basesystem apt apt-conf-sisyphus etcnet openssh-server passwd sysklogd net-tools e2fsprogs"
+
+    mkdir -p $INSTALL_ROOT/var/lib/rpm
+    rpm --root $INSTALL_ROOT  --initdb
+    $APT_GET install $PKG_LIST
+
+    if [ $? -ne 0 ]; then
+       echo "Failed to download the rootfs, aborting."
+       return 1
+    fi
+
+    mv "$INSTALL_ROOT" "$cache/rootfs"
+    echo "Download complete."
+
+    return 0
+}
+
+copy_altlinux()
+{
+
+    # make a local copy of the minialtlinux
+    echo -n "Copying rootfs to $rootfs_path ..."
+    #cp -a $cache/rootfs-$arch $rootfs_path || return 1
+    # i prefer rsync (no reason really)
+    mkdir -p $rootfs_path
+    rsync -a $cache/rootfs/ $rootfs_path/
+    return 0
+}
+
+update_altlinux()
+{
+    chroot $cache/rootfs apt-get update
+    chroot $cache/rootfs apt-get -y dist-upgrade
+}
+
+install_altlinux()
+{
+    mkdir -p /var/lock/subsys/
+    (
+       flock -x 200
+       if [ $? -ne 0 ]; then
+           echo "Cache repository is busy."
+           return 1
+       fi
+
+       echo "Checking cache download in $cache/rootfs ... "
+       if [ ! -e "$cache/rootfs" ]; then
+           download_altlinux
+           if [ $? -ne 0 ]; then
+               echo "Failed to download 'altlinux base'"
+               return 1
+           fi
+        else
+           echo "Cache found. Updating..."
+            update_altlinux
+           if [ $? -ne 0 ]; then
+               echo "Failed to update 'altlinux base', continuing with last known good cache"
+            else
+                echo "Update finished"
+           fi
+       fi
+
+       echo "Copy $cache/rootfs to $rootfs_path ... "
+       copy_altlinux
+       if [ $? -ne 0 ]; then
+           echo "Failed to copy rootfs"
+           return 1
+       fi
+
+       return 0
+
+       ) 200>/var/lock/subsys/lxc
+
+    return $?
+}
+
+copy_configuration()
+{
+
+    mkdir -p $config_path
+    grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
+    cat <<EOF >> $config_path/config
+lxc.utsname = $name
+lxc.tty = 4
+lxc.pts = 1024
+lxc.mount  = $config_path/fstab
+#networking
+lxc.network.type = $lxc_network_type
+lxc.network.flags = up
+lxc.network.link = $lxc_network_link
+lxc.network.name = veth0
+lxc.network.mtu = 1500
+EOF
+if [ ! -z ${ipv4} ]; then
+    cat <<EOF >> $config_path/config
+lxc.network.ipv4 = $ipv4
+EOF
+fi
+if [ ! -z ${gw} ]; then
+    cat <<EOF >> $config_path/config
+lxc.network.ipv4.gateway = $gw
+EOF
+fi
+if [ ! -z ${ipv6} ]; then
+    cat <<EOF >> $config_path/config
+lxc.network.ipv6 = $ipv6
+EOF
+fi
+if [ ! -z ${gw6} ]; then
+    cat <<EOF >> $config_path/config
+lxc.network.ipv6.gateway = $gw6
+EOF
+fi
+    cat <<EOF >> $config_path/config
+#cgroups
+lxc.cgroup.devices.deny = a
+# /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 10:135 rwm
+EOF
+
+    cat <<EOF > $config_path/fstab
+proc            $rootfs_path/proc         proc    nodev,noexec,nosuid 0 0
+sysfs           $rootfs_path/sys          sysfs defaults  0 0
+EOF
+
+    if [ $? -ne 0 ]; then
+       echo "Failed to add configuration"
+       return 1
+    fi
+
+    return 0
+}
+
+clean()
+{
+
+    if [ ! -e $cache ]; then
+       exit 0
+    fi
+
+    # lock, so we won't purge while someone is creating a repository
+    (
+       flock -n -x 200
+       if [ $? != 0 ]; then
+           echo "Cache repository is busy."
+           exit 1
+       fi
+
+       echo -n "Purging the download cache for ALTLinux-$release..."
+       rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
+       exit 0
+
+    ) 200>/var/lock/subsys/lxc
+}
+
+usage()
+{
+    cat <<EOF
+usage:
+    $1 -n|--name=<container_name>
+        [-p|--path=<path>] [-c|--clean] [-R|--release=<ALTLinux_release>]
+        [-4|--ipv4=<ipv4 address>] [-6|--ipv6=<ipv6 address>]
+        [-g|--gw=<gw address>] [-d|--dns=<dns address>]
+        [-P|--profile=<name of the profile>]
+        [-A|--arch=<arch of the container>]
+        [-h|--help]
+Mandatory args:
+  -n,--name         container name, used to as an identifier for that container from now on
+Optional args:
+  -p,--path         path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in and case
+  -c,--clean        clean the cache
+  -R,--release      ALTLinux release for the new container. if the host is ALTLinux, then it will defaultto the host's release.
+  -4,--ipv4         specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24
+  -6,--ipv6         specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64
+  -g,--gw           specify the default gw, eg. 192.168.1.1
+  -G,--gw6          specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596
+  -d,--dns          specify the DNS server, eg. 192.168.1.2
+  -P,--profile      Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache.
+  -A,--arch         NOT USED YET. Define what arch the container will be [i686,x86_64]
+  -h,--help         print this help
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n:P:cR:4:6:g:d: -l help,path:,name:,profile:,clean,release:ipv4:ipv6:gw:dns: -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+       -h|--help)      usage $0 && exit 0;;
+       -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+       -P|--profile)   profile=$2; shift 2;;
+       -c|--clean)     clean=$2; shift 2;;
+       -R|--release)   release=$2; shift 2;;
+       -4|--ipv4)      ipv4=$2; shift 2;;
+       -6|--ipv6)      ipv6=$2; shift 2;;
+       -g|--gw)        gw=$2; shift 2;;
+       -d|--dns)       dns=$2; shift 2;;
+       --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ ! -z "$clean" -a -z "$path" ]; then
+    clean || exit 1
+    exit 0
+fi
+
+type apt-get >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+    echo "'apt-get' command is missing"
+    exit 1
+fi
+
+if [ -z "$path" ]; then
+    path=$default_path
+fi
+
+if [ -z "$profile" ]; then
+    profile=$default_profile
+fi
+
+if [ -z "$release" ]; then
+    if [ "$is_altlinux" ]; then
+        release=$(cat /etc/altlinux-release |awk '/^ALT/ {print $3}')
+    else
+        echo "This is not a ALTLinux host and release missing, use -R|--release to specify release"
+        exit 1
+    fi
+fi
+
+if [ -z "$ipv4" -a -z "$ipv6" ]; then
+    BOOTPROTO="dhcp"
+else
+    BOOTPROTO="static"
+fi
+
+if [ "$(id -u)" != "0" ]; then
+    echo "This script should be run as 'root'"
+    exit 1
+fi
+
+rootfs_path=$path/$name/rootfs
+config_path=$default_path/$name
+cache=$cache_base/$release/$profile
+
+if [ -f $config_path/config ]; then
+    echo "A container with that name exists, chose a different name"
+    exit 1
+fi
+
+# check for 'lxc.rootfs' passed in through default config by lxc-create
+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then
+    rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'`
+fi
+
+install_altlinux
+if [ $? -ne 0 ]; then
+    echo "failed to install altlinux"
+    exit 1
+fi
+
+configure_altlinux
+if [ $? -ne 0 ]; then
+    echo "failed to configure altlinux for a container"
+    exit 1
+fi
+
+copy_configuration
+if [ $? -ne 0 ]; then
+    echo "failed write configuration file"
+    exit 1
+fi
+
+if [ ! -z $clean ]; then
+    clean || exit 1
+    exit 0
+fi
+echo "container rootfs and config created"
+echo "container is configured for lxc.network.type=veth and lxc.network.link=virbr0 (which is default if you have libvirt runnig)"
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-archlinux b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-archlinux
new file mode 100755 (executable)
index 0000000..d5a8fb6
--- /dev/null
@@ -0,0 +1,466 @@
+#!/bin/bash
+
+#
+# template script for generating Arch linux container for LXC
+#
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Alexander Vladimirov <idkfa@vlan1.ru>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# defaults
+arch=$(arch)
+cache=/var/cache/lxc/arch/${arch}
+lxc_network_type="veth"
+lxc_network_link="br0"
+default_path=/var/lib/lxc
+default_rc_locale="en-US.UTF-8"
+default_rc_timezone="UTC"
+host_mirror="http://mirrors.kernel.org/archlinux/\$repo/os/$arch"
+
+# sort of minimal package set
+base_packages=(
+    "filesystem"
+    "initscripts"
+    "coreutils"
+    "module-init-tools"
+    "procps"
+    "psmisc"
+    "pacman"
+    "bash"
+    "syslog-ng"
+    "cronie"
+    "iproute2"
+    "iputils"
+    "inetutils"
+    "dhcpcd"
+    "dnsutils"
+    "nano"
+    "grep"
+    "less"
+    "gawk"
+    "sed"
+    "tar"
+    "wget"
+    "gzip"
+    "which"
+)
+declare -a additional_packages
+
+[ -f /etc/arch-release ] && is_arch=true
+
+# find and extract parameter value from given config file
+# ${1} - file to read parameter from
+# ${2} - parameter name
+# ${result} - result value on success
+function read_parameter_value {
+    [ -f ${1} ] && [ "${2}" ] || return 1
+    local pattern="^[[:space:]]*${2}[[:space:]]*=[[:space:]]*"
+    local str=$(grep "${pattern}" "${1}")
+    local str=${str/#$(grep -o "${pattern}" "${1}")/}
+    result=${str//\"/}
+    return 0
+}
+
+# split comma-separated string into an array
+# ${1} - string to split
+# ${2} - separator (default is ",")
+# ${result} - result value on success
+function split_string {
+    local ifs=${IFS}
+    IFS="${2:-,}"
+    read -a result < <(echo "${1}")
+    IFS=${ifs}
+    return 0
+}
+
+# Arch-specific preconfiguration for container
+function configure_arch {
+    # read locale and timezone defaults from system rc.conf if running on Arch
+    if [ "${is_arch}" ]; then
+        read_parameter_value "/etc/rc.conf" "LOCALE"
+        rc_locale=${result:-${default_rc_locale}}
+        read_parameter_value "/etc/rc.conf" "TIMEZONE"
+        rc_timezone=${result:-${default_rc_timezone}}
+    else
+        rc_locale=${default_rc_locale}
+        rc_timezone=${default_rc_timezone}
+    fi
+
+    echo "Setting up rc.conf"
+    cat > "${rootfs_path}/etc/rc.conf" << EOF
+# /etc/rc.conf - Main Configuration for Arch Linux
+LOCALE="${rc_locale}"
+DAEMON_LOCALE="no"
+HARDWARECLOCK="local"
+TIMEZONE="${rc_timezone}"
+KEYMAP=us
+CONSOLEFONT=
+CONSOLEMAP=
+USECOLOR="yes"
+MODULES=()
+HOSTNAME="${name}"
+interface=eth0
+address=
+netmask=
+broadcast=
+gateway=
+DAEMONS=(syslog-ng crond network)
+EOF
+
+    if [ -e "${rootfs_path}/etc/locale.gen" ]; then
+        sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen"
+        if [ ! "${rc_locale}" = "en_US.UTF-8" ]; then
+            echo "${rc_locale} ${rc_locale##*.}" >> "${rootfs_path}/etc/locale.gen"
+        fi
+        chroot "${rootfs_path}" locale-gen
+    fi
+    cp "${rootfs_path}/usr/share/zoneinfo/${rc_timezone}" \
+       "${rootfs_path}/etc/localtime"
+
+    echo "Setting up rc.sysinit"
+    cat > "${rootfs_path}/etc/rc.sysinit.lxc" << EOF
+#!/bin/bash
+. /etc/rc.conf
+. /etc/rc.d/functions
+
+echo "starting Arch Linux"
+rm -f \$(find /var/run -name '*pid')
+rm -f /run/daemons/*
+rm -f /var/lock/subsys/*
+rm -f /etc/mtab
+touch /etc/mtab
+run_hook sysinit_end
+EOF
+
+    echo "Setting up rc.shutdown"
+    cat > "${rootfs_path}/etc/rc.shutdown.lxc" << EOF
+#!/bin/bash
+. /etc/rc.conf
+. /etc/rc.d/functions
+stty onlcr
+run_hook shutdown_start
+[[ -x /etc/rc.local.shutdown ]] && /etc/rc.local.shutdown
+stop_all_daemons
+run_hook shutdown_prekillall
+kill_all
+run_hook shutdown_postkillall
+[[ \${TIMEZONE} ]] && cp --remove-destination "/usr/share/zoneinfo/\${TIMEZONE}" /etc/localtime
+halt -w
+umount -a -r -t nodevtmpfs,notmpfs,nosysfs,noproc,nodevpts -O no_netdev
+run_hook shutdown_postumount
+run_hook shutdown_poweroff
+if [[ \${RUNLEVEL} = 0 ]]; then
+    poweroff -d -f -i
+else
+    reboot -d -f -i
+fi
+# vim: set ts=2 sw=2 noet:
+EOF
+    chmod 755 "${rootfs_path}/etc/rc.shutdown.lxc" "${rootfs_path}/etc/rc.sysinit.lxc"
+
+    echo "Setting up inittab"
+    cat > "${rootfs_path}/etc/inittab" << EOF
+id:3:initdefault:
+rc::sysinit:/etc/rc.sysinit.lxc
+rs:S1:wait:/etc/rc.single
+rm:2345:wait:/etc/rc.multi
+rh:06:wait:/etc/rc.shutdown.lxc
+su:S:wait:/sbin/sulogin -p
+c1:2345:respawn:/sbin/agetty -8 38400 tty1 linux
+EOF
+
+    echo "Setting up hosts"
+    cat > "${rootfs_path}/etc/hosts" << EOF
+127.0.0.1   localhost.localdomain   localhost ${name}
+::1     localhost.localdomain   localhost
+EOF
+
+    echo "Setting up nameserver"
+    grep nameserver /etc/resolv.conf > "${rootfs_path}/etc/resolv.conf"
+
+    echo "Setting up device nodes"
+    mkdir -m 755 "${rootfs_path}/dev/pts"
+    mkdir -m 1777 "${rootfs_path}/dev/shm"
+    mknod -m 666 "${rootfs_path}/dev/null" c 1 3
+    mknod -m 666 "${rootfs_path}/dev/full" c 1 7
+    mknod -m 666 "${rootfs_path}/dev/random" c 1 8
+    mknod -m 666 "${rootfs_path}/dev/urandom" c 1 9
+    mknod -m 666 "${rootfs_path}/dev/tty0" c 4 0
+    mknod -m 666 "${rootfs_path}/dev/tty1" c 4 1
+    mknod -m 666 "${rootfs_path}/dev/tty2" c 4 2
+    mknod -m 666 "${rootfs_path}/dev/tty3" c 4 3
+    mknod -m 666 "${rootfs_path}/dev/tty4" c 4 4
+    mknod -m 600 "${rootfs_path}/dev/initctl" p
+    mknod -m 666 "${rootfs_path}/dev/tty" c 5 0
+    mknod -m 666 "${rootfs_path}/dev/console" c 5 1
+    mknod -m 666 "${rootfs_path}/dev/ptmx" c 5 2
+
+    return 0
+}
+
+# write container configuration files
+function copy_configuration {
+    mkdir -p "${config_path}"
+    grep -q "^lxc.rootfs" "${config_path}/config" 2>/dev/null || echo "lxc.rootfs=${rootfs_path}" >> "${config_path}/config"
+    cat > "${config_path}/config" << EOF
+lxc.utsname=${name}
+lxc.tty=4
+lxc.pts=1024
+lxc.mount=${config_path}/fstab
+#networking
+lxc.network.type=${lxc_network_type}
+lxc.network.flags=up
+lxc.network.link=${lxc_network_link}
+lxc.network.name=eth0
+lxc.network.mtu=1500
+#cgroups
+lxc.cgroup.devices.deny = a
+# /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
+# /dev/pts
+lxc.cgroup.devices.allow = c 136:* rwm
+lxc.cgroup.devices.allow = c 5:2 rwm
+# rtc
+lxc.cgroup.devices.allow = c 254:0 rwm
+EOF
+
+    cat > "${config_path}/fstab" << EOF
+none ${rootfs_path}/dev/pts devpts defaults 0 0
+none ${rootfs_path}/proc proc nodev,noexec,nosuid 0 0
+none ${rootfs_path}/sys sysfs defaults 0 0
+none ${rootfs_path}/dev/shm tmpfs defaults 0 0
+EOF
+
+    if [ ${?} -ne 0 ]; then
+        echo "Failed to configure container"
+        return 1
+    fi
+
+    return 0
+}
+
+# lock chroot and mount subdirectories before installing container
+function mount_chroot {
+    echo "mounting chroot"
+    umask 0022
+    [ -e "${rootfs_path}/sys" ] || mkdir "${rootfs_path}/sys"
+    mount -t sysfs sysfs "${rootfs_path}/sys"
+    [ -e "${rootfs_path}/proc" ] || mkdir "${rootfs_path}/proc"
+    mount -t proc proc "${rootfs_path}/proc"
+    [ -e "${rootfs_path}/dev" ] || mkdir "${rootfs_path}/dev"
+    mount -t tmpfs dev "${rootfs_path}/dev" -o mode=0755,size=10M,nosuid
+    mknod -m 666 "${rootfs_path}/dev/null" c 1 3
+    mknod -m 666 "${rootfs_path}/dev/zero" c 1 5
+    mknod -m 600 "${rootfs_path}/dev/console" c 5 1
+    mknod -m 644 "${rootfs_path}/dev/random" c 1 8
+    mknod -m 644 "${rootfs_path}/dev/urandom" c 1 9
+    mknod -m 666 "${rootfs_path}/dev/tty" c 5 0
+    mknod -m 666 "${rootfs_path}/dev/tty0" c 4 0
+    mknod -m 666 "${rootfs_path}/dev/full" c 1 7
+    ln -s /proc/kcore "${rootfs_path}/dev/core"
+    ln -s /proc/self/fd "${rootfs_path}/dev/fd"
+    ln -s /proc/self/fd/0 "${rootfs_path}/dev/stdin"
+    ln -s /proc/self/fd/1 "${rootfs_path}/dev/stdout"
+    ln -s /proc/self/fd/2 "${rootfs_path}/dev/stderr"
+    [ -e "${rootfs_path}/dev/shm" ] || mkdir "${rootfs_path}/dev/shm"
+    mount -t tmpfs shm "${rootfs_path}/dev/shm" -o nodev,nosuid,size=128M
+    [ -e "${rootfs_path}/dev/pts" ] || mkdir "${rootfs_path}/dev/pts"
+    mount -t devpts devpts "${rootfs_path}/dev/pts" -o newinstance,ptmxmode=666
+    ln -s pts/ptmx "${rootfs_path}/dev/ptmx"
+    [ -e "${cache_dir}" ] || mkdir -p "${cache_dir}"
+    [ -e "${rootfs_path}/${cache_dir}" ] || mkdir -p "${rootfs_path}/${cache_dir}"
+    mount -o bind "${cache_dir}" "${rootfs_path}/${cache_dir}"
+    if [ -n "${host_mirror_path}" ]; then
+        [ -e "${rootfs_path}/${host_mirror_path}" ] || mkdir -p "${rootfs_path}/${host_mirror_path}"
+        mount -o bind "${host_mirror_path}" "${rootfs_path}/${host_mirror_path}"
+        mount -o remount,ro,bind "${host_mirror_path}" "${rootfs_path}/${host_mirror_path}"
+    fi
+    trap 'umount_chroot' EXIT INT QUIT TERM HUP
+}
+
+function umount_chroot {
+    if [ -z "${umount_done}" ]; then
+        echo "unmounting chroot"
+        umount "${rootfs_path}/proc"
+        umount "${rootfs_path}/sys"
+        umount "${rootfs_path}/dev/pts"
+        umount "${rootfs_path}/dev/shm"
+        umount "${rootfs_path}/dev"
+        umount "${rootfs_path}/${cache_dir}"
+        [ -n "${host_mirror_path}" ] && umount "${rootfs_path}/${host_mirror_path}"
+        umount_done=1
+    fi
+}
+
+# install packages within container chroot
+function install_arch {
+    pacman_config=$(mktemp)
+
+    cat <<EOF > "${pacman_config}"
+[options]
+HoldPkg      = pacman glibc
+SyncFirst    = pacman
+Architecture = auto
+#IgnorePkg    = udev
+[core]
+Include = /etc/pacman.d/mirrorlist
+Server = ${host_mirror}
+[extra]
+Include = /etc/pacman.d/mirrorlist
+Server = ${host_mirror}
+[community]
+Include = /etc/pacman.d/mirrorlist
+Server = ${host_mirror}
+EOF
+
+    mkdir -p "${rootfs_path}/var/lib/pacman/sync"
+    mkdir -p "${rootfs_path}/etc"
+
+    if echo "${host_mirror}" | grep -q 'file://'; then
+        host_mirror_path=$(echo "${host_mirror}" | sed -E 's#file://(/.*)/\$repo/os/\$arch#\1#g')
+    fi
+    cache_dir=$( (grep -m 1 '^CacheDir' "${pacman_config}" || echo 'CacheDir = /var/cache/pacman/pkg') | sed 's/CacheDir\s*=\s*//')
+    mount_chroot
+    params="--root ${rootfs_path} --config=${pacman_config} --noconfirm"
+    if ! pacman -Sydd ${params} --dbonly udev; then
+        echo "Failed to preinstall udev package record"
+        return 1
+    fi
+    if ! pacman -S ${params} ${base_packages[@]}; then
+        echo "Failed to install container packages"
+        return 1
+    fi
+    [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}"
+    mv "${pacman_config}" "${rootfs_path}/etc/pacman.conf"
+    umount_chroot
+    return 0
+}
+
+usage()
+{
+    cat <<EOF
+usage:
+    ${1} -n|--name=<container_name>
+        [-P|--packages=<pkg1,pkg2,...>] [-p|--path=<path>] [-h|--help]
+Mandatory args:
+  -n,--name         container name, used to as an identifier for that container from now on
+Optional args:
+  -p,--path         path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case
+  -P,--packages     preinstall additional packages, comma-separated list
+  -h,--help         print this help
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:P:n:cm: -l help,path:,packages:,name:,clean,mirror: -- "${@}")
+if [ ${?} -ne 0 ]; then
+    usage $(basename ${0})
+    exit 1
+fi
+eval set -- "${options}"
+
+while true
+do
+    case "${1}" in
+    -h|--help)      usage ${0} && exit 0;;
+    -p|--path)      path=${2}; shift 2;;
+    -n|--name)      name=${2}; shift 2;;
+    -P|--packages)  additional_packages=${2}; shift 2;;
+    -m|--mirror)    host_mirror=${2}; shift 2;;
+    --)             shift 1; break ;;
+    *)              break ;;
+    esac
+done
+
+if [ -z "${name}" ]; then
+    echo "missing required 'name' parameter"
+    exit 1
+fi
+
+type pacman >/dev/null 2>&1
+if [ ${?} -ne 0 ]; then
+    echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman"
+    exit 1
+fi
+
+if [ -z "${path}" ]; then
+    path="${default_path}/${name}"
+fi
+
+if [ "${EUID}" != "0" ]; then
+    echo "This script should be run as 'root'"
+    exit 1
+fi
+
+rootfs_path="${path}/rootfs"
+# check for 'lxc.rootfs' passed in through default config by lxc-create
+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then
+    rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'`
+fi
+config_path="${default_path}/${name}"
+
+revert()
+{
+    echo "Interrupted, so cleaning up"
+    lxc-destroy -n "${name}"
+    # maybe was interrupted before copy config
+    rm -rf "${path}/${name}"
+    rm -rf "${default_path}/${name}"
+    exit 1
+}
+
+trap revert SIGHUP SIGINT SIGTERM
+
+copy_configuration
+if [ ${?} -ne 0 ]; then
+    echo "failed write configuration file"
+    rm -rf "${config_path}"
+    exit 1
+fi
+
+if [ ${#additional_packages[@]} -gt 0 ]; then
+    split_string ${additional_packages}
+    base_packages+=(${result[@]})
+fi
+
+install_arch
+if [ ${?} -ne 0 ]; then
+    echo "failed to install Arch linux"
+    rm -rf "${config_path}" "${path}"
+    exit 1
+fi
+
+configure_arch
+if [ ${?} -ne 0 ]; then
+    echo "failed to configure Arch linux for a container"
+    rm -rf "${config_path}" "${path}"
+    exit 1
+fi
+
+echo "container rootfs and config created"
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-busybox b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-busybox
new file mode 100755 (executable)
index 0000000..1314b9e
--- /dev/null
@@ -0,0 +1,320 @@
+#!/bin/bash
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Daniel Lezcano <daniel.lezcano@free.fr>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+install_busybox()
+{
+    rootfs=$1
+    name=$2
+    res=0
+    tree="\
+$rootfs/selinux \
+$rootfs/dev \
+$rootfs/home \
+$rootfs/root \
+$rootfs/etc \
+$rootfs/etc/init.d \
+$rootfs/bin \
+$rootfs/sbin \
+$rootfs/proc \
+$rootfs/mnt \
+$rootfs/tmp \
+$rootfs/var/log \
+$rootfs/usr/share/udhcpc \
+$rootfs/dev/pts \
+$rootfs/dev/shm \
+$rootfs/lib \
+$rootfs/usr/lib \
+$rootfs/lib64 \
+$rootfs/usr/lib64"
+
+    mkdir -p $tree || return 1
+    chmod 755 $tree || return 1
+
+    pushd $rootfs/dev > /dev/null || return 1
+
+    # minimal devices needed for busybox
+    mknod tty c 5 0       || res=1
+    mknod console c 5 1   || res=1
+    chmod 666 tty console || res=1
+    mknod tty0 c 4 0      || res=1
+    mknod tty1 c 4 0      || res=1
+    mknod tty5 c 4 0      || res=1
+    chmod 666 tty0        || res=1
+    mknod ram0 b 1 0      || res=1
+    chmod 600 ram0        || res=1
+    mknod null c 1 3      || res=1
+    chmod 666 null        || res=1
+
+    popd > /dev/null
+
+    # root user defined
+    cat <<EOF >> $rootfs/etc/passwd
+root:x:0:0:root:/root:/bin/sh
+EOF
+
+    cat <<EOF >> $rootfs/etc/group
+root:x:0:root
+EOF
+
+    # mount everything
+    cat <<EOF >> $rootfs/etc/init.d/rcS
+#!/bin/sh
+/bin/syslogd
+/bin/mount -a
+/bin/udhcpc
+EOF
+
+    # executable
+    chmod 744 $rootfs/etc/init.d/rcS || return 1
+
+    # mount points
+    cat <<EOF >> $rootfs/etc/fstab
+proc  /proc      proc    defaults     0      0
+shm   /dev/shm   tmpfs   defaults     0      0
+EOF
+
+    # writable and readable for other
+    chmod 644 $rootfs/etc/fstab || return 1
+
+    # launch rcS first then make a console available
+    # and propose a shell on the tty, the last one is
+    # not needed
+    cat <<EOF >> $rootfs/etc/inittab
+::sysinit:/etc/init.d/rcS
+tty1::respawn:/bin/getty -L tty1 115200 vt100
+console::askfirst:/bin/sh
+EOF
+    # writable and readable for other
+    chmod 644 $rootfs/etc/inittab || return 1
+
+    cat <<EOF >> $rootfs/usr/share/udhcpc/default.script
+#!/bin/sh
+
+case "\$1" in
+       deconfig)
+               ip addr flush dev \$interface
+                ;;
+
+       renew|bound)
+
+                # flush all the routes
+               if [ -n "\$router" ]; then
+                        ip route del default 2> /dev/null
+               fi
+
+                # check broadcast
+                if [ -n "\$broadcast" ]; then
+                        broadcast="broadcast \$broadcast"
+                fi
+
+                # add a new ip address
+               ip addr add \$ip/\$mask \$broadcast dev \$interface
+
+               if [ -n "\$router" ]; then
+                        ip route add default via \$router dev \$interface
+                fi
+
+               [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf
+               for i in \$dns ; do
+                       echo nameserver \$i >> /etc/resolv.conf
+               done
+               ;;
+esac
+exit 0
+EOF
+
+    chmod 744 $rootfs/usr/share/udhcpc/default.script
+
+    return $res
+}
+
+configure_busybox()
+{
+    rootfs=$1
+
+    functions="\
+       [ [[ addgroup adduser adjtimex ar arp arping ash awk basename \
+       brctl bunzip2 bzcat bzip2 cal cat catv chattr chgrp chmod \
+       chown chpasswd chpst chroot chrt chvt cksum clear cmp comm \
+       cp cpio crond crontab cryptpw cut date dc dd deallocvt \
+       delgroup deluser df dhcprelay diff dirname dmesg dnsd dos2unix \
+       du dumpkmap dumpleases echo ed egrep eject env envdir envuidgid \
+       ether-wake expand expr fakeidentd false fbset fdformat fdisk \
+       fetchmail fgrep find findfs fold free freeramdisk fsck \
+       fsck.minix ftpget ftpput fuser getopt getty grep gunzip gzip \
+       halt hdparm head hexdump hostid hostname httpd hwclock id \
+       ifconfig ifdown ifenslave ifup inetd init insmod install ip \
+       ipaddr ipcalc ipcrm ipcs iplink iproute iprule iptunnel \
+       kbd_mode kill killall killall5 klogd last length less linux32 \
+       linux64 linuxrc ln loadfont loadkmap logger login logname \
+       logread losetup lpd lpq lpr ls lsattr lsmod lzmacat makedevs \
+       md5sum mdev mesg microcom mkdir mkfifo mkfs.minix mknod mkswap \
+       mktemp modprobe more mount mountpoint msh mt mv nameif nc \
+       netstat nice nmeter nohup nslookup od openvt passwd patch \
+       pgrep pidof ping ping6 pipe_progress pivot_root pkill poweroff \
+       printenv printf ps pscan pwd raidautorun rdate readahead \
+       readlink readprofile realpath reboot renice reset resize rm \
+       rmdir rmmod route rpm rpm2cpio run-parts runlevel runsv \
+       runsvdir rx script sed sendmail seq setarch setconsole \
+       setkeycodes setlogcons setsid setuidgid sh sha1sum slattach \
+       sleep softlimit sort split start-stop-daemon stat strings \
+       stty su sulogin sum sv svlogd swapoff swapon switch_root \
+       sync sysctl syslogd tac tail tar taskset tcpsvd tee telnet \
+       telnetd test tftp tftpd time top touch tr traceroute \
+       true tty ttysize udhcpc udhcpd udpsvd umount uname uncompress \
+       unexpand uniq unix2dos unlzma unzip uptime usleep uudecode \
+       uuencode vconfig vi vlock watch watchdog wc wget which \
+       who whoami xargs yes zcat zcip"
+
+    type busybox >/dev/null
+
+    if [ $? -ne 0 ]; then
+       echo "busybox executable is not accessible"
+       return 1
+    fi
+
+    file $(which busybox) | grep -q "statically linked"
+    if [ $? -ne 0 ]; then
+       echo "warning : busybox is not statically linked."
+       echo "warning : The template script may not correctly"
+       echo "warning : setup the container environment."
+    fi
+
+    # copy busybox in the rootfs
+    cp $(which busybox) $rootfs/bin
+    if [ $? -ne 0 ]; then
+       echo "failed to copy busybox in the rootfs"
+       return 1
+    fi
+
+    # do hardlink to busybox for the different commands
+    for i in $functions; do ln $rootfs/bin/busybox $rootfs/bin/$i; done
+
+    # relink /sbin/init
+    ln $rootfs/bin/busybox $rootfs/sbin/init
+
+    # passwd exec must be setuid
+    chmod +s $rootfs/bin/passwd
+    touch $rootfs/etc/shadow
+    chroot $rootfs /bin/passwd -d root
+
+    echo "No password for 'root', please change !"
+
+    return 0
+}
+
+copy_configuration()
+{
+    path=$1
+    rootfs=$2
+    name=$3
+
+grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+cat <<EOF >> $path/config
+lxc.utsname = $name
+lxc.tty = 1
+lxc.pts = 1
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+EOF
+
+if [ -d "$rootfs/lib" ]; then
+cat <<EOF >> $path/config
+lxc.mount.entry=/lib $rootfs/lib none ro,bind 0 0
+lxc.mount.entry=/usr/lib $rootfs/usr/lib none ro,bind 0 0
+EOF
+fi
+
+if [ -d "/lib64" ] && [ -d "$rootfs/lib64" ]; then
+cat <<EOF >> $path/config
+lxc.mount.entry=/lib64 $rootfs/lib64 none ro,bind 0 0
+EOF
+fi
+
+if [ -d "/usr/lib64" ] && [ -d "$rootfs/usr/lib64" ]; then
+cat <<EOF >> $path/config
+lxc.mount.entry=/usr/lib64 $rootfs/usr/lib64 none ro,bind 0 0
+EOF
+fi
+}
+
+usage()
+{
+    cat <<EOF
+$1 -h|--help -p|--path=<path>
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n: -l help,path:,name: -- "$@")
+if [ $? -ne 0 ]; then
+        usage $(basename $0)
+       exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+        -h|--help)      usage $0 && exit 0;;
+        -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+        --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ "$(id -u)" != "0" ]; then
+    echo "This script should be run as 'root'"
+    exit 1
+fi
+
+if [ -z "$path" ]; then
+    echo "'path' parameter is required"
+    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_busybox $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed to install busybox's rootfs"
+    exit 1
+fi
+
+configure_busybox $rootfs
+if [ $? -ne 0 ]; then
+    echo "failed to configure busybox template"
+    exit 1
+fi
+
+copy_configuration $path $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed to write configuration file"
+    exit 1
+fi
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-debian b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-debian
new file mode 100755 (executable)
index 0000000..8d8a26c
--- /dev/null
@@ -0,0 +1,343 @@
+#!/bin/bash
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Daniel Lezcano <daniel.lezcano@free.fr>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+SUITE=${SUITE:-squeeze}
+MIRROR=${MIRROR:-http://cdn.debian.net/debian}
+
+configure_debian()
+{
+    rootfs=$1
+    hostname=$2
+
+    # squeeze only has /dev/tty and /dev/tty0 by default,
+    # therefore creating missing device nodes for tty1-4.
+    for tty in $(seq 1 4); do
+       if [ ! -e $rootfs/dev/tty$tty ]; then
+           mknod $rootfs/dev/tty$tty c 4 $tty
+       fi
+    done
+
+    # configure the inittab
+    cat <<EOF > $rootfs/etc/inittab
+id:3:initdefault:
+si::sysinit:/etc/init.d/rcS
+l0:0:wait:/etc/init.d/rc 0
+l1:1:wait:/etc/init.d/rc 1
+l2:2:wait:/etc/init.d/rc 2
+l3:3:wait:/etc/init.d/rc 3
+l4:4:wait:/etc/init.d/rc 4
+l5:5:wait:/etc/init.d/rc 5
+l6:6:wait:/etc/init.d/rc 6
+# Normally not reached, but fallthrough in case of emergency.
+z6:6:respawn:/sbin/sulogin
+1:2345:respawn:/sbin/getty 38400 console
+c1:12345:respawn:/sbin/getty 38400 tty1 linux
+c2:12345:respawn:/sbin/getty 38400 tty2 linux
+c3:12345:respawn:/sbin/getty 38400 tty3 linux
+c4:12345:respawn:/sbin/getty 38400 tty4 linux
+p6::ctrlaltdel:/sbin/init 6 
+p0::powerfail:/sbin/init 0
+EOF
+
+    # disable selinux in debian
+    mkdir -p $rootfs/selinux
+    echo 0 > $rootfs/selinux/enforce
+
+    # configure the network using the dhcp
+    cat <<EOF > $rootfs/etc/network/interfaces
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet dhcp
+EOF
+
+    # set the hostname
+    cat <<EOF > $rootfs/etc/hostname
+$hostname
+EOF
+
+    # reconfigure some services
+    if [ -z "$LANG" ]; then
+       chroot $rootfs locale-gen en_US.UTF-8 UTF-8
+       chroot $rootfs update-locale LANG=en_US.UTF-8
+    else
+       chroot $rootfs locale-gen $LANG $(echo $LANG | cut -d. -f2)
+       chroot $rootfs update-locale LANG=$LANG
+    fi
+
+    # remove pointless services in a container
+    chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove
+    chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove
+    chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove
+    chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove
+
+    echo "root:root" | chroot $rootfs chpasswd
+    echo "Root password is 'root', please change !"
+
+    return 0
+}
+
+cleanup()
+{
+    rm -rf $cache/partial-$SUITE-$arch
+    rm -rf $cache/rootfs-$SUITE-$arch
+}
+
+download_debian()
+{
+    packages=\
+ifupdown,\
+locales,\
+libui-dialog-perl,\
+dialog,\
+isc-dhcp-client,\
+netbase,\
+net-tools,\
+iproute,\
+openssh-server
+
+    cache=$1
+    arch=$2
+
+    trap cleanup EXIT SIGHUP SIGINT SIGTERM
+    # check the mini debian was not already downloaded
+    mkdir -p "$cache/partial-$SUITE-$arch"
+    if [ $? -ne 0 ]; then
+       echo "Failed to create '$cache/partial-$SUITE-$arch' directory"
+       return 1
+    fi
+
+    # download a mini debian into a cache
+    echo "Downloading debian minimal ..."
+    debootstrap --verbose --variant=minbase --arch=$arch \
+       --include=$packages \
+       "$SUITE" "$cache/partial-$SUITE-$arch" $MIRROR
+    if [ $? -ne 0 ]; then
+       echo "Failed to download the rootfs, aborting."
+       return 1
+    fi
+
+    mv "$1/partial-$SUITE-$arch" "$1/rootfs-$SUITE-$arch"
+    echo "Download complete."
+    trap EXIT
+    trap SIGINT
+    trap SIGTERM
+    trap SIGHUP
+
+    return 0
+}
+
+copy_debian()
+{
+    cache=$1
+    arch=$2
+    rootfs=$3
+
+    # make a local copy of the minidebian
+    echo -n "Copying rootfs to $rootfs..."
+    mkdir -p $rootfs
+    rsync -a "$cache/rootfs-$SUITE-$arch"/ $rootfs/ || return 1
+    return 0
+}
+
+install_debian()
+{
+    cache="/var/cache/lxc/debian"
+    rootfs=$1
+    mkdir -p /var/lock/subsys/
+    (
+       flock -x 200
+       if [ $? -ne 0 ]; then
+           echo "Cache repository is busy."
+           return 1
+       fi
+
+       arch=$(dpkg --print-architecture)
+
+       echo "Checking cache download in $cache/rootfs-$SUITE-$arch ... "
+       if [ ! -e "$cache/rootfs-$SUITE-$arch" ]; then
+           download_debian $cache $arch
+           if [ $? -ne 0 ]; then
+               echo "Failed to download 'debian base'"
+               return 1
+           fi
+       fi
+
+       copy_debian $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
+    hostname=$3
+
+    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+    cat <<EOF >> $path/config
+lxc.tty = 4
+lxc.pts = 1024
+lxc.utsname = $hostname
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+lxc.cgroup.devices.deny = a
+# /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
+
+# mounts point
+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
+lxc.mount.entry=sysfs sys sysfs defaults  0 0
+EOF
+
+    if [ $? -ne 0 ]; then
+       echo "Failed to add configuration"
+       return 1
+    fi
+
+    return 0
+}
+
+clean()
+{
+    cache="/var/cache/lxc/debian"
+
+    if [ ! -e $cache ]; then
+       exit 0
+    fi
+
+    # lock, so we won't purge while someone is creating a repository
+    (
+       flock -n -x 200
+       if [ $? != 0 ]; then
+           echo "Cache repository is busy."
+           exit 1
+       fi
+
+       echo -n "Purging the download cache..."
+       rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
+       exit 0
+
+    ) 200>/var/lock/subsys/lxc
+}
+
+usage()
+{
+    cat <<EOF
+$1 -h|--help -p|--path=<path> --clean
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
+if [ $? -ne 0 ]; then
+        usage $(basename $0)
+       exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+        -h|--help)      usage $0 && exit 0;;
+        -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+       -c|--clean)     clean=$2; shift 2;;
+        --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ ! -z "$clean" -a -z "$path" ]; then
+    clean || exit 1
+    exit 0
+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_debian $rootfs
+if [ $? -ne 0 ]; then
+    echo "failed to install debian"
+    exit 1
+fi
+
+configure_debian $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed to configure debian for a container"
+    exit 1
+fi
+
+copy_configuration $path $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed write configuration file"
+    exit 1
+fi
+
+if [ ! -z $clean ]; then
+    clean || exit 1
+    exit 0
+fi
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-fedora b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-fedora
new file mode 100755 (executable)
index 0000000..fbcd69e
--- /dev/null
@@ -0,0 +1,421 @@
+#!/bin/bash
+
+#
+# template script for generating fedora container for LXC
+#
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Daniel Lezcano <daniel.lezcano@free.fr>
+# Ramez Hanna <rhanna@informatiq.org>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#Configurations
+arch=$(arch)
+cache_base=/var/cache/lxc/fedora/$arch
+default_path=/var/lib/lxc
+root_password=root
+
+# is this fedora?
+[ -f /etc/fedora-release ] && is_fedora=true
+
+if [ "$arch" = "i686" ]; then
+    arch=i386
+fi
+
+configure_fedora()
+{
+
+    # disable selinux in fedora
+    mkdir -p $rootfs_path/selinux
+    echo 0 > $rootfs_path/selinux/enforce
+
+   # configure the network using the dhcp
+    cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
+DEVICE=eth0
+BOOTPROTO=dhcp
+ONBOOT=yes
+HOSTNAME=${name}
+NM_CONTROLLED=no
+TYPE=Ethernet
+MTU=${MTU}
+EOF
+
+    # set the hostname
+    cat <<EOF > ${rootfs_path}/etc/sysconfig/network
+NETWORKING=yes
+HOSTNAME=${name}
+EOF
+
+    # set minimal hosts
+    cat <<EOF > $rootfs_path/etc/hosts
+127.0.0.1 localhost $name
+EOF
+
+    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit
+    sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit
+    # don't mount devpts, for pete's sake
+    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit
+    sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit
+
+    chroot ${rootfs_path} chkconfig udev-post off
+    chroot ${rootfs_path} chkconfig network on
+
+    dev_path="${rootfs_path}/dev"
+    rm -rf $dev_path
+    mkdir -p $dev_path
+    mknod -m 666 ${dev_path}/null c 1 3
+    mknod -m 666 ${dev_path}/zero c 1 5
+    mknod -m 666 ${dev_path}/random c 1 8
+    mknod -m 666 ${dev_path}/urandom c 1 9
+    mkdir -m 755 ${dev_path}/pts
+    mkdir -m 1777 ${dev_path}/shm
+    mknod -m 666 ${dev_path}/tty c 5 0
+    mknod -m 666 ${dev_path}/tty0 c 4 0
+    mknod -m 666 ${dev_path}/tty1 c 4 1
+    mknod -m 666 ${dev_path}/tty2 c 4 2
+    mknod -m 666 ${dev_path}/tty3 c 4 3
+    mknod -m 666 ${dev_path}/tty4 c 4 4
+    mknod -m 600 ${dev_path}/console c 5 1
+    mknod -m 666 ${dev_path}/full c 1 7
+    mknod -m 600 ${dev_path}/initctl p
+    mknod -m 666 ${dev_path}/ptmx c 5 2
+
+    echo "setting root passwd to $root_password"
+    echo "root:$root_password" | chroot $rootfs_path chpasswd
+
+    # specifying this in the initial packages doesn't always work.
+    echo "installing fedora-release package"
+    chroot ${rootfs_path} yum --releasever=${release} -y install fedora-release
+
+    # silence some needless startup errors
+    touch ${rootfs_path}/etc/fstab
+
+    # give us a console on /dev/console
+    sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \
+        ${rootfs_path}/etc/sysconfig/init
+
+    return 0
+}
+
+download_fedora()
+{
+
+    # check the mini fedora was not already downloaded
+    INSTALL_ROOT=$cache/partial
+    mkdir -p $INSTALL_ROOT
+    if [ $? -ne 0 ]; then
+       echo "Failed to create '$INSTALL_ROOT' directory"
+       return 1
+    fi
+
+    # download a mini fedora into a cache
+    echo "Downloading fedora minimal ..."
+    YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
+    PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release"
+    MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch"
+
+    DOWNLOAD_OK=no
+    for trynumber in 1 2 3; do
+        [ $trynumber != 1 ] && echo "Trying again..."
+        MIRROR_URL=$(curl -s -S -f "$MIRRORLIST_URL" | head -n2 | tail -n1)
+        if [ $? -ne 0 ] || [ -z "$MIRROR_URL" ]; then
+            echo "Failed to get a mirror"
+            continue
+        fi
+        RELEASE_URL="$MIRROR_URL/Packages/fedora-release-$release-1.noarch.rpm"
+        echo "Fetching from $RELEASE_URL"
+        curl -f "$RELEASE_URL" > $INSTALL_ROOT/fedora-release-$release.noarch.rpm
+        if [ $? -ne 0 ]; then
+            echo "Failed to download fedora release rpm"
+            continue
+        fi
+        DOWNLOAD_OK=yes
+        break
+    done
+    if [ $DOWNLOAD_OK != yes ]; then
+        echo "Aborting"
+        return 1
+    fi
+
+    mkdir -p $INSTALL_ROOT/var/lib/rpm
+    rpm --root $INSTALL_ROOT  --initdb
+    rpm --root $INSTALL_ROOT -ivh $INSTALL_ROOT/fedora-release-$release.noarch.rpm
+    $YUM install $PKG_LIST
+
+    if [ $? -ne 0 ]; then
+       echo "Failed to download the rootfs, aborting."
+       return 1
+    fi
+
+    mv "$INSTALL_ROOT" "$cache/rootfs"
+    echo "Download complete."
+
+    return 0
+}
+
+copy_fedora()
+{
+
+    # make a local copy of the minifedora
+    echo -n "Copying rootfs to $rootfs_path ..."
+    #cp -a $cache/rootfs-$arch $rootfs_path || return 1
+    # i prefer rsync (no reason really)
+    mkdir -p $rootfs_path
+    rsync -a $cache/rootfs/ $rootfs_path/
+    return 0
+}
+
+update_fedora()
+{
+    chroot $cache/rootfs yum -y update
+}
+
+install_fedora()
+{
+    mkdir -p /var/lock/subsys/
+    (
+       flock -x 200
+       if [ $? -ne 0 ]; then
+           echo "Cache repository is busy."
+           return 1
+       fi
+
+       echo "Checking cache download in $cache/rootfs ... "
+       if [ ! -e "$cache/rootfs" ]; then
+           download_fedora
+           if [ $? -ne 0 ]; then
+               echo "Failed to download 'fedora base'"
+               return 1
+           fi
+        else
+           echo "Cache found. Updating..."
+            update_fedora
+           if [ $? -ne 0 ]; then
+               echo "Failed to update 'fedora base', continuing with last known good cache"
+            else
+                echo "Update finished"
+           fi
+       fi
+
+       echo "Copy $cache/rootfs to $rootfs_path ... "
+       copy_fedora
+       if [ $? -ne 0 ]; then
+           echo "Failed to copy rootfs"
+           return 1
+       fi
+
+       return 0
+
+       ) 200>/var/lock/subsys/lxc
+
+    return $?
+}
+
+copy_configuration()
+{
+
+    mkdir -p $config_path
+    grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
+    cat <<EOF >> $config_path/config
+lxc.utsname = $name
+lxc.tty = 4
+lxc.pts = 1024
+lxc.mount  = $config_path/fstab
+
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+
+#cgroups
+lxc.cgroup.devices.deny = a
+# /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
+EOF
+
+    cat <<EOF > $config_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
+}
+
+clean()
+{
+
+    if [ ! -e $cache ]; then
+       exit 0
+    fi
+
+    # lock, so we won't purge while someone is creating a repository
+    (
+       flock -x 200
+       if [ $? != 0 ]; then
+           echo "Cache repository is busy."
+           exit 1
+       fi
+
+       echo -n "Purging the download cache for Fedora-$release..."
+       rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
+       exit 0
+
+    ) 200>/var/lock/subsys/lxc
+}
+
+usage()
+{
+    cat <<EOF
+usage:
+    $1 -n|--name=<container_name>
+        [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>] [-A|--arch=<arch of the container>]
+        [-h|--help]
+Mandatory args:
+  -n,--name         container name, used to as an identifier for that container from now on
+Optional args:
+  -p,--path         path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case
+  -c,--clean        clean the cache
+  -R,--release      Fedora release for the new container. if the host is Fedora, then it will defaultto the host's release.
+  -A,--arch         NOT USED YET. Define what arch the container will be [i686,x86_64]
+  -h,--help         print this help
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n:cR: -l help,path:,name:,clean,release: -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+       -h|--help)      usage $0 && exit 0;;
+       -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+       -c|--clean)     clean=$2; shift 2;;
+        -R|--release)   release=$2; shift 2;;
+       --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ ! -z "$clean" -a -z "$path" ]; then
+    clean || exit 1
+    exit 0
+fi
+
+needed_pkgs=""
+type yum >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+    needed_pkgs="yum $needed_pkgs"
+fi
+
+type curl >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+    needed_pkgs="curl $needed_pkgs"
+fi
+
+if [ -n "$needed_pkgs" ]; then
+    echo "Missing commands: $needed_pkgs"
+    echo "Please install these using \"sudo apt-get install $needed_pkgs\""
+    exit 1
+fi
+
+if [ -z "$path" ]; then
+    path=$default_path
+fi
+
+if [ -z "$release" ]; then
+    if [ "$is_fedora" ]; then
+        release=$(cat /etc/fedora-release |awk '/^Fedora/ {print $3}')
+    else
+        echo "This is not a fedora host and release missing, defaulting to 14. use -R|--release to specify release"
+        release=14
+    fi
+fi
+
+if [ "$(id -u)" != "0" ]; then
+    echo "This script should be run as 'root'"
+    exit 1
+fi
+
+
+rootfs_path=$path/rootfs
+# check for 'lxc.rootfs' passed in through default config by lxc-create
+if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then
+    rootfs_path=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'`
+fi
+config_path=$default_path/$name
+cache=$cache_base/$release
+
+revert()
+{
+    echo "Interrupted, so cleaning up"
+    lxc-destroy -n $name
+    # maybe was interrupted before copy config
+    rm -rf $path/$name
+    rm -rf $default_path/$name
+    echo "exiting..."
+    exit 1
+}
+
+trap revert SIGHUP SIGINT SIGTERM
+
+copy_configuration
+if [ $? -ne 0 ]; then
+    echo "failed write configuration file"
+    exit 1
+fi
+
+install_fedora
+if [ $? -ne 0 ]; then
+    echo "failed to install fedora"
+    exit 1
+fi
+
+configure_fedora
+if [ $? -ne 0 ]; then
+    echo "failed to configure fedora for a container"
+    exit 1
+fi
+
+
+if [ ! -z $clean ]; then
+    clean || exit 1
+    exit 0
+fi
+echo "container rootfs and config created"
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-opensuse b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-opensuse
new file mode 100755 (executable)
index 0000000..26cee6a
--- /dev/null
@@ -0,0 +1,398 @@
+#!/bin/bash
+
+#
+# template script for generating suse container for LXC
+#
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Daniel Lezcano <daniel.lezcano@free.fr>
+# Frederic Crozat <fcrozat@suse.com>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+DISTRO=12.1
+
+configure_opensuse()
+{
+    rootfs=$1
+    hostname=$2
+
+   # set network as static, but everything is done by LXC outside the container
+   cat <<EOF > $rootfs/etc/sysconfig/network/ifcfg-eth0
+STARTMODE='auto'
+BOOTPROTO='static'
+EOF
+
+   # set default route
+   IP=$(/sbin/ip route | awk '/default/ { print $3 }')
+   echo "default $IP - -" > $rootfs/etc/sysconfig/network/routes
+
+   # create empty fstab
+   touch $rootfs/etc/fstab
+
+    # create minimal /dev
+    mknod -m 666 $rootfs/dev/random c 1 8
+    mknod -m 666 $rootfs/dev/urandom c 1 9
+    mkdir -m 755 $rootfs/dev/pts
+    mkdir -m 1777 $rootfs/dev/shm
+    mknod -m 666 $rootfs/dev/tty c 5 0
+    mknod -m 600 $rootfs/dev/console c 5 1
+    mknod -m 666 $rootfs/dev/tty0 c 4 0
+    mknod -m 666 $rootfs/dev/tty1 c 4 1
+    mknod -m 666 $rootfs/dev/tty2 c 4 2
+    mknod -m 666 $rootfs/dev/tty3 c 4 3
+    mknod -m 666 $rootfs/dev/tty4 c 4 4
+    ln -s null $rootfs/dev/tty10
+    mknod -m 666 $rootfs/dev/full c 1 7
+    mknod -m 666 $rootfs/dev/ptmx c 5 2
+    ln -s /proc/self/fd $rootfs/dev/fd
+    ln -s /proc/kcore $rootfs/dev/core
+    mkdir -m 755 $rootfs/dev/mapper
+    mknod -m 600 $rootfs/dev/mapper/control c 10 60
+    mkdir -m 755 $rootfs/dev/net
+    mknod -m 666 $rootfs/dev/net/tun c 10 200
+
+    # set the hostname
+    cat <<EOF > $rootfs/etc/HOSTNAME
+$hostname
+EOF
+
+    # do not use hostname from HOSTNAME variable
+    cat <<EOF >> $rootfs/etc/sysconfig/cron
+unset HOSTNAME
+EOF
+
+    # set minimal hosts
+    cat <<EOF > $rootfs/etc/hosts
+127.0.0.1 localhost $hostname
+EOF
+
+    # disable various services
+    # disable yast->bootloader in container
+    cat <<EOF > $rootfs/etc/sysconfig/bootloader
+LOADER_TYPE=none
+LOADER_LOCATION=none
+EOF
+
+    # cut down inittab
+    cat <<EOF > $rootfs/etc/inittab
+id:3:initdefault:
+si::bootwait:/etc/init.d/boot
+l0:0:wait:/etc/init.d/rc 0
+l1:1:wait:/etc/init.d/rc 1
+l2:2:wait:/etc/init.d/rc 2
+l3:3:wait:/etc/init.d/rc 3
+l6:6:wait:/etc/init.d/rc 6
+ls:S:wait:/etc/init.d/rc S
+~~:S:respawn:/sbin/sulogin
+p6::ctrlaltdel:/sbin/init 6
+p0::powerfail:/sbin/init 0
+cons:2345:respawn:/sbin/mingetty --noclear console screen
+c1:2345:respawn:/sbin/mingetty --noclear tty1 screen
+EOF
+
+    # set /dev/console as securetty
+    cat << EOF >> $rootfs/etc/securetty
+console
+EOF
+
+    cat <<EOF >> $rootfs/etc/sysconfig/boot
+# disable root fsck
+ROOTFS_FSCK="0"
+ROOTFS_BLKDEV="/dev/null"
+EOF
+
+
+    # remove pointless services in a container
+    chroot $rootfs /sbin/insserv -r -f boot.udev boot.loadmodules boot.device-mapper boot.clock boot.swap boot.klog kbd
+
+    echo "Please change root-password !"
+    echo "root:root" | chroot $rootfs chpasswd
+
+    return 0
+}
+
+download_opensuse()
+{
+    cache=$1
+    arch=$2
+
+    if [ ! -x /usr/bin/build ]; then
+       echo "Could not create openSUSE template :"
+       echo "you need to install \"build\" package"
+       return 1
+    fi
+
+    # check the mini opensuse 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 opensuse into a cache
+    echo "Downloading opensuse minimal ..."
+    mkdir -p "$cache/partial-$arch-packages"
+    zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss
+    zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update
+    zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update
+    zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base sysvinit-init
+    cat > $cache/partial-$arch-packages/opensuse.conf << EOF
+Preinstall: aaa_base bash coreutils diffutils
+Preinstall: filesystem fillup glibc grep insserv libacl1 libattr1
+Preinstall: libbz2-1 libgcc46 libxcrypt libncurses5 pam
+Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1
+Preinstall: liblzma5 libcap2 libpcre0
+Preinstall: libpopt0 libelf1 liblua5_1
+
+RunScripts: aaa_base
+
+Support: zypper
+Support: patterns-openSUSE-base
+Support: lxc
+Prefer: sysvinit-init
+
+Ignore: patterns-openSUSE-base:patterns-openSUSE-yast2_install_wf
+EOF
+
+    CLEAN_BUILD=1 BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" /usr/lib/build/init_buildsystem  --clean --cachedir $cache/partial-$arch-cache --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch
+    chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss repo-oss
+    chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update
+    chroot $cache/partial-$arch rpm -e patterns-openSUSE-base
+    umount $cache/partial-$arch/proc
+#   really clean the image
+    rm -fr $cache/partial-$arch/{.build,.guessed_dist,.srcfiles*,installed-pkg}
+    rm -fr $cache/partial-$arch/dev
+#    make sure we have a minimal /dev
+    mkdir -p "$cache/partial-$arch/dev"
+    mknod -m 666 $cache/partial-$arch/dev/null c 1 3
+    mknod -m 666 $cache/partial-$arch/dev/zero c 1 5
+#   create mtab symlink
+    rm -f $cache/partial-$arch/etc/mtab
+    ln -sf /proc/self/mounts $cache/partial-$arch/etc/mtab
+    if [ $? -ne 0 ]; then
+       echo "Failed to download the rootfs, aborting."
+       return 1
+    fi
+
+    rm -fr "$cache/partial-$arch-packages"
+    mv "$1/partial-$arch" "$1/rootfs-$arch"
+    echo "Download complete."
+
+    return 0
+}
+
+copy_opensuse()
+{
+    cache=$1
+    arch=$2
+    rootfs=$3
+
+    # make a local copy of the mini opensuse
+    echo -n "Copying rootfs to $rootfs ..."
+    mkdir -p $rootfs
+    rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
+    return 0
+}
+
+install_opensuse()
+{
+    cache="/var/cache/lxc/opensuse"
+    rootfs=$1
+    mkdir -p /var/lock/subsys/
+    (
+       flock -x 200
+       if [ $? -ne 0 ]; then
+           echo "Cache repository is busy."
+           return 1
+       fi
+
+       arch=$(arch)
+
+       echo "Checking cache download in $cache/rootfs-$arch ... "
+       if [ ! -e "$cache/rootfs-$arch" ]; then
+           download_opensuse $cache $arch
+           if [ $? -ne 0 ]; then
+               echo "Failed to download 'opensuse base'"
+               return 1
+           fi
+       fi
+
+       echo "Copy $cache/rootfs-$arch to $rootfs ... "
+       copy_opensuse $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
+
+    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+
+lxc.tty = 4
+lxc.pts = 1024
+lxc.mount  = $path/fstab
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+
+lxc.cgroup.devices.deny = a
+# /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
+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
+}
+
+clean()
+{
+    cache="/var/cache/lxc/opensuse"
+
+    if [ ! -e $cache ]; then
+       exit 0
+    fi
+
+    # lock, so we won't purge while someone is creating a repository
+    (
+       flock -x 200
+       if [ $? != 0 ]; then
+           echo "Cache repository is busy."
+           exit 1
+       fi
+
+       echo -n "Purging the download cache..."
+       rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
+       exit 0
+
+    ) 200>/var/lock/subsys/lxc
+}
+
+usage()
+{
+    cat <<EOF
+$1 -h|--help -p|--path=<path> --clean
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+       -h|--help)      usage $0 && exit 0;;
+       -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+       -c|--clean)     clean=$2; shift 2;;
+       --)             shift 1; break ;;
+       *)              break ;;
+    esac
+done
+
+if [ ! -z "$clean" -a -z "$path" ]; then
+    clean || exit 1
+    exit 0
+fi
+
+type zypper > /dev/null
+if [ $? -ne 0 ]; then
+    echo "'zypper' 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_opensuse $rootfs
+if [ $? -ne 0 ]; then
+    echo "failed to install opensuse"
+    exit 1
+fi
+
+configure_opensuse $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed to configure opensuse for a container"
+    exit 1
+fi
+
+copy_configuration $path $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed write configuration file"
+    exit 1
+fi
+
+if [ ! -z $clean ]; then
+    clean || exit 1
+    exit 0
+fi
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-sshd b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-sshd
new file mode 100755 (executable)
index 0000000..80362a0
--- /dev/null
@@ -0,0 +1,233 @@
+#!/bin/bash
+
+#
+# lxc: linux Container library
+
+# Authors:
+# Daniel Lezcano <daniel.lezcano@free.fr>
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+install_sshd()
+{
+    rootfs=$1
+
+    tree="\
+$rootfs/var/run/sshd \
+$rootfs/var/empty/sshd \
+$rootfs/var/lib/empty/sshd \
+$rootfs/etc/ssh \
+$rootfs/dev/shm \
+$rootfs/run/shm \
+$rootfs/proc \
+$rootfs/bin \
+$rootfs/sbin \
+$rootfs/usr \
+$rootfs/tmp \
+$rootfs/home \
+$rootfs/root \
+$rootfs/lib \
+$rootfs/lib64"
+
+    mkdir -p $tree
+    if [ $? -ne 0 ]; then
+        return 1
+    fi
+
+    return 0
+}
+
+configure_sshd()
+{
+    rootfs=$1
+
+    cat <<EOF > $rootfs/etc/passwd
+root:x:0:0:root:/root:/bin/bash
+sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
+EOF
+
+    cat <<EOF > $rootfs/etc/group
+root:x:0:root
+sshd:x:74:
+EOF
+
+ssh-keygen -t rsa -f $rootfs/etc/ssh/ssh_host_rsa_key
+ssh-keygen -t dsa -f $rootfs/etc/ssh/ssh_host_dsa_key
+
+    # by default setup root password with no password
+    cat <<EOF > $rootfs/etc/ssh/sshd_config
+Port 22
+Protocol 2
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_dsa_key
+UsePrivilegeSeparation yes
+KeyRegenerationInterval 3600
+ServerKeyBits 768
+SyslogFacility AUTH
+LogLevel INFO
+LoginGraceTime 120
+PermitRootLogin yes
+StrictModes yes
+RSAAuthentication yes
+PubkeyAuthentication yes
+IgnoreRhosts yes
+RhostsRSAAuthentication no
+HostbasedAuthentication no
+PermitEmptyPasswords yes
+ChallengeResponseAuthentication no
+EOF
+
+    if [ -n "$auth_key" -a -f "$auth_key" ]; then
+       u_path="/root/.ssh"
+       root_u_path="$rootfs/$u_path"
+       mkdir -p $root_u_path
+       cp $auth_key "$root_u_path/authorized_keys"
+       chown -R 0:0 "$rootfs/$u_path"
+       chmod 700 "$rootfs/$u_path"
+
+       echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys"
+    fi
+
+    return 0
+}
+
+copy_configuration()
+{
+    path=$1
+    rootfs=$2
+    name=$3
+
+    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+lxc.pts = 1024
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+lxc.mount.entry=/dev dev none ro,bind 0 0
+lxc.mount.entry=/lib lib none ro,bind 0 0
+lxc.mount.entry=/bin bin none ro,bind 0 0
+lxc.mount.entry=/usr usr none ro,bind 0 0
+lxc.mount.entry=/sbin sbin none ro,bind 0 0
+lxc.mount.entry=tmpfs var/run/sshd tmpfs mode=0644 0 0
+lxc.mount.entry=/usr/share/lxc/templates/lxc-sshd sbin/init none bind 0 0
+lxc.mount.entry=proc proc proc nodev,noexec,nosuid 0 0
+EOF
+
+    # if no .ipv4 section in config, then have the container run dhcp
+    grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp
+
+    if [ "$(uname -m)" = "x86_64" ]; then
+        cat <<EOF >> $path/config
+lxc.mount.entry=/lib64 lib64 none ro,bind 0 0
+EOF
+    fi
+}
+
+usage()
+{
+    cat <<EOF
+$1 -h|--help -p|--path=<path>
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:n:S: -l help,path:,name:,auth-key: -- "$@")
+if [ $? -ne 0 ]; then
+        usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+        -h|--help)      usage $0 && exit 0;;
+        -p|--path)      path=$2; shift 2;;
+       -n|--name)      name=$2; shift 2;;
+       -S|--auth-key)  auth_key=$2; shift 2;;
+        --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ "$(id -u)" != "0" ]; then
+    echo "This script should be run as 'root'"
+    exit 1
+fi
+
+if [ $0 == "/sbin/init" ]; then
+
+    type ${libexecdir}/lxc-init
+    if [ $? -ne 0 ]; then
+        echo "'lxc-init is not accessible on the system"
+        exit 1
+    fi
+
+    type sshd
+    if [ $? -ne 0 ]; then
+        echo "'sshd' is not accessible on the system "
+        exit 1
+    fi
+
+    # run dhcp?
+    if [ -f /run-dhcp ]; then
+        type dhclient
+        if [ $? -ne 0 ]; then
+            echo "can't find dhclient"
+            exit 1
+        fi
+       touch /etc/fstab
+        rm -f /dhclient.conf
+        cat > /dhclient.conf << EOF
+send host-name "<hostname>";
+EOF
+       ifconfig eth0 up
+        dhclient eth0 -cf /dhclient.conf
+    fi
+
+    exec ${libexecdir}/lxc-init -- /usr/sbin/sshd
+    exit 1
+fi
+
+if [ -z "$path" ]; then
+    echo "'path' parameter is required"
+    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_sshd $rootfs
+if [ $? -ne 0 ]; then
+    echo "failed to install sshd's rootfs"
+    exit 1
+fi
+
+configure_sshd $rootfs
+if [ $? -ne 0 ]; then
+    echo "failed to configure sshd template"
+    exit 1
+fi
+
+copy_configuration $path $rootfs $name
+if [ $? -ne 0 ]; then
+    echo "failed to write configuration file"
+    exit 1
+fi
diff --git a/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu
new file mode 100755 (executable)
index 0000000..4d4bc30
--- /dev/null
@@ -0,0 +1,719 @@
+#!/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@canonical.com>
+# Copyright © 2010 Wilhelm Meier
+# Author: Wilhelm Meier <wilhelm.meier@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
+
+    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
+    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
+
+# uncomment the next line to run the container 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
+devtmpfs        dev          devtmpfs 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
+
+    # reconfigure some services
+    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
+
+    # 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/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu-cloud b/lxc/0.8.0~rc1-4ubuntu37/templates/lxc-ubuntu-cloud
new file mode 100755 (executable)
index 0000000..16de831
--- /dev/null
@@ -0,0 +1,407 @@
+#!/bin/bash
+
+# template script for generating ubuntu container for LXC based on released cloud
+# images
+#
+# Copyright © 2012 Serge Hallyn <serge.hallyn@canonical.com>
+#
+# 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
+
+copy_configuration()
+{
+    path=$1
+    rootfs=$2
+    name=$3
+    arch=$4
+    release=$5
+
+    if [ $arch = "i386" ]; then
+        arch="i686"
+    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.tty = 4
+lxc.pts = 1024
+lxc.mount  = $path/fstab
+lxc.arch = $arch
+lxc.cap.drop = sys_module mac_admin
+lxc.pivotdir = lxc_putold
+
+# uncomment the next line to run the container 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
+devtmpfs        dev          devtmpfs defaults 0 0
+EOF
+
+    # 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
+
+    return 0
+}
+
+usage()
+{
+    cat <<EOF
+LXC Container configuration for Ubuntu Cloud images.
+
+Generic Options
+[ -r | --release <release> ]: Release name of container, defaults to host
+[ -a | --arch ]: Arhcitecture of container, defaults to host arcitecture
+[ -C | --cloud ]: Configure container for use with meta-data service, defaults to no
+[ -T | --tarball ]: Location of tarball
+[ -d | --debug ]: Run with 'set -x' to debug errors
+[ -s | --stream]: Use specified stream rather than 'released'
+
+Options, mutually exclusive of "-C" and "--cloud":
+  [ -i | --hostid ]:    HostID for cloud-init, defaults to random string
+  [ -u | --userdata ]:  Cloud-init user-data file to configure container on start
+  [ -S | --auth-key ]:  SSH Public key file to inject into container
+  [ -L | --nolocales ]: Do not copy host's locales into container
+
+EOF
+    return 0
+}
+
+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+release=lucid
+if [ -f /etc/lsb-release ]; then
+    . /etc/lsb-release
+    case "$DISTRIB_CODENAME" in
+        lucid|natty|oneiric|precise|quantal)
+            release=$DISTRIB_CODENAME
+        ;;
+    esac
+fi
+
+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
+        # note: arm images don't exist before oneiric;  are called armhf in
+        # precise and later;  and are not supported by the query, so we don't actually
+        # support them yet (see check later on).  When Query2 is available,
+        # we'll use that to enable arm images.
+        arch="armel"
+    fi
+fi
+
+debug=0
+hostarch=$arch
+cloud=0
+locales=1
+flushcache=0
+stream="released"
+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;;
+    -a|--arch)         arch=$2; shift 2;;
+    -i|--hostid)       host_id=$2; shift 2;;
+    -u|--userdata)     userdata=$2; shift 2;;
+    -C|--cloud)        cloud=1; shift 1;;
+    -S|--auth-key)     auth_key=$2; shift 2;;
+    -L|--no_locales)   locales=0; shift 2;;
+    -T|--tarball)      tarball=$2; shift 2;;
+    -d|--debug)        debug=1; shift 1;;
+    -s|--stream)       stream=$2; shift 2;;
+    --)                shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ $debug -eq 1 ]; then
+    set -x
+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
+
+if [ $arch != "i386" -a $arch != "amd64" ]; then
+    echo "Only i386 and amd64 are supported by the ubuntu cloud template."
+    exit 1
+fi
+
+if [ "$stream" != "daily" -a "$stream" != "released" ]; then
+    echo "Only 'daily' and 'released' streams are supported"
+    exit 1
+fi
+
+if [ -n "$userdata" ]; then
+    if [ ! -f "$userdata" ]; then
+        echo "Userdata ($userdata) does not exist"
+        exit 1
+    else
+        userdata=`readlink -f $userdata`
+    fi
+fi
+
+if [ -n "$auth_key" ]; then
+    if [ ! -f "$auth_key" ]; then
+        echo "--auth-key=${auth_key} must reference a file"
+        exit 1
+    fi
+    auth_key=$(readlink -f "${auth_key}") ||
+        { echo "failed to get full path for auth_key"; 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
+
+type ubuntu-cloudimg-query
+type wget
+
+# determine the url, tarball, and directory names
+# download if needed
+cache="/var/cache/lxc/cloud-$release"
+
+mkdir -p $cache
+
+if [ -n "$tarball" ]; then
+    url2="$tarball"
+else
+    url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`
+    url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'`
+fi
+
+filename=`basename $url2`
+
+wgetcleanup()
+{
+    rm -f $filename
+}
+
+buildcleanup()
+{
+    cd $rootfs
+    umount -l $cache/$xdir || true
+    rm -rf $cache
+}
+
+# if the release doesn't have a *-rootfs.tar.gz, then create one from the
+# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating
+# a tarball from the mounted image.
+build_root_tgz()
+{
+    url=$1
+    filename=$2
+
+    xdir=`mktemp -d -p .`
+    tarname=`basename $url`
+    imgname="$release-*-cloudimg-$arch.img"
+    trap buildcleanup EXIT SIGHUP SIGINT SIGTERM
+    if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then
+        rm -f $tarname
+        echo "Downloading cloud image from $url"
+        wget $url || { echo "Couldn't find cloud image $url."; exit 1; }
+    fi
+    echo "Creating new cached cloud image rootfs"
+    tar --wildcards -zxf $tarname $imgname
+    mount -o loop $imgname $xdir
+    (cd $xdir; tar zcf ../$filename .)
+    umount $xdir
+    rm -f $tarname $imgname
+    rmdir $xdir
+    echo "New cloud image cache created"
+    trap EXIT
+    trap SIGHUP
+    trap SIGINT
+    trap SIGTERM
+}
+
+mkdir -p /var/lock/subsys/
+(
+    flock -x 200
+
+    cd $cache
+    if [ $flushcache -eq 1 ]; then
+        echo "Clearing the cached images"
+        rm -f $filename
+    fi
+
+    trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM
+    if [ ! -f $filename ]; then
+        wget $url2 || build_root_tgz $url1 $filename
+    fi
+    trap EXIT
+    trap SIGHUP
+    trap SIGINT
+    trap SIGTERM
+
+    echo "Extracting container rootfs"
+    mkdir -p $rootfs
+    cd $rootfs
+    tar -zxf $cache/$filename
+
+
+    if [ $cloud -eq 0 ]; then
+        echo "Configuring for running outside of a cloud environment"
+        echo "If you want to configure for a cloud evironment, please use '-- -C' to create the container"
+
+        seed_d=$rootfs/var/lib/cloud/seed/nocloud-net
+        rhostid=$(uuidgen | cut -c -8)
+        host_id=${hostid:-$rhostid}
+        mkdir -p $seed_d
+
+        cat > "$seed_d/meta-data" <<EOF
+instance-id: lxc-$host_id
+EOF
+        if [ -n "$auth_key" ]; then
+            {
+            echo "public-keys:" &&
+            sed -e '/^$/d' -e 's,^,- ,' "$auth_key" "$auth_key"
+            } >> "$seed_d/meta-data"
+            [ $? -eq 0 ] ||
+                { echo "failed to write public keys to metadata"; exit 1; }
+        fi
+
+        rm $rootfs/etc/hostname
+
+        if [ $locales -eq 1 ]; then
+            cp /usr/lib/locale/locale-archive $rootfs/usr/lib/locale/locale-archive
+        fi
+
+        if [ -f "$userdata" ]; then
+            echo "Using custom user-data"
+            cp $userdata $seed_d/user-data
+        else
+
+            if [ -z "$MIRROR" ]; then
+                MIRROR="http://archive.ubuntu.com/ubuntu"
+            fi
+
+            cat > "$seed_d/user-data" <<EOF
+#cloud-config
+output: {all: '| tee -a /var/log/cloud-init-output.log'}
+apt_mirror: $MIRROR
+manage_etc_hosts: localhost
+locale: $(/usr/bin/locale | awk -F= '/LANG=/ {print$NF}')
+password: ubuntu
+chpasswd: { expire: False }
+EOF
+        fi
+
+    else
+
+        echo "Configured for running in a cloud environment."
+        echo "If you do not have a meta-data service, this container will likely be useless."
+
+    fi
+) 200>/var/lock/subsys/lxc-ubucloud
+
+copy_configuration $path $rootfs $name $arch $release
+
+echo "Container $name created."
+exit 0
+
+# vi: ts=4 expandtab