* /usr/lib/lxc/templates of lxc 0.7.5-3ubuntu63 on Ubuntu 12.04.1
authormitty <mitty@7d2118f6-f56c-43e7-95a2-4bb3031d96e7>
Tue, 16 Oct 2012 05:21:37 +0000 (05:21 +0000)
committermitty <mitty@7d2118f6-f56c-43e7-95a2-4bb3031d96e7>
Tue, 16 Oct 2012 05:21:37 +0000 (05:21 +0000)
git-svn-id: https://lab.mitty.jp/svn/lab/vendor@174 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

lxc/0.7.5-3ubuntu63/templates/lxc-busybox [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-debian [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-fedora [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-opensuse [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-sshd [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-ubuntu [new file with mode: 0755]
lxc/0.7.5-3ubuntu63/templates/lxc-ubuntu-cloud [new file with mode: 0755]

diff --git a/lxc/0.7.5-3ubuntu63/templates/lxc-busybox b/lxc/0.7.5-3ubuntu63/templates/lxc-busybox
new file mode 100755 (executable)
index 0000000..01d40f5
--- /dev/null
@@ -0,0 +1,314 @@
+#!/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
+
+cat <<EOF >> $path/config
+lxc.utsname = $name
+lxc.tty = 1
+lxc.pts = 1
+lxc.rootfs = $rootfs
+# 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
+
+rootfs=$path/rootfs
+
+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.7.5-3ubuntu63/templates/lxc-debian b/lxc/0.7.5-3ubuntu63/templates/lxc-debian
new file mode 100755 (executable)
index 0000000..b5ced57
--- /dev/null
@@ -0,0 +1,371 @@
+#!/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:2: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
+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
+    LANG="${LANG:-en_US.UTF-8}"
+
+    locale="$LANG $(echo $LANG | cut -d. -f2)"
+    chroot $rootfs echo "locales locales/default_environment_locale select $LANG" | chroot $rootfs sh -c "LANG=C debconf-set-selections"
+    chroot $rootfs echo "locales locales/default_environment_locale seen true" | chroot $rootfs sh -c "LANG=C debconf-set-selections"
+    chroot $rootfs echo "locales locales/locales_to_be_generated seen true" | chroot $rootfs sh -c "LANG=C debconf-set-selections"
+    chroot $rootfs sed -i -e "0,/^[# ]*$locale *$/ s/^[# ]*$locale *$/$locale/" /etc/locale.gen
+    chroot $rootfs sh -c "LANG=C dpkg-reconfigure locales -f noninteractive"
+
+    # remove pointless services in a container
+    chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh remove # S
+    chroot $rootfs /usr/sbin/update-rc.d checkroot.sh stop 09 S .
+
+    chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove # 0 6
+    chroot $rootfs /usr/sbin/update-rc.d umountfs start 09 0 6 .
+
+    chroot $rootfs /usr/sbin/update-rc.d -f umountroot remove # 0 6
+    chroot $rootfs /usr/sbin/update-rc.d umountroot start 10 0 6 .
+
+    # The following initscripts don't provide an empty start or stop block.
+    # To prevent them being enabled on upgrades, we leave a start link on
+    # runlevel 3.
+    chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove # S 0 6
+    chroot $rootfs /usr/sbin/update-rc.d hwclock.sh start 10 3 .
+
+    chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove # S
+    chroot $rootfs /usr/sbin/update-rc.d hwclockfirst start 08 3 .
+
+    chroot $rootfs /usr/sbin/update-rc.d -f module-init-tools remove # S
+    chroot $rootfs /usr/sbin/update-rc.d module-init-tools start 10 3 .
+
+    echo "root:root" | chroot $rootfs chpasswd
+    echo "Root password is 'root', please change !"
+
+    return 0
+}
+
+download_debian()
+{
+    packages=\
+ifupdown,\
+locales,\
+libui-dialog-perl,\
+dialog,\
+dhcp3-client,\
+netbase,\
+net-tools,\
+iproute,\
+openssh-server
+
+    cache=$1
+    arch=$2
+
+    # 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."
+
+    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
+
+       # 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)
+           case $arch in
+               686)           arch="i386";;
+               x86_64)        arch="amd64";;
+               ppc)           arch="powerpc";;
+           esac
+       fi
+
+       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
+    name=$3
+
+    cat >> $path/config << EOF
+# $path/config
+
+## Container
+lxc.utsname                             = $name
+lxc.rootfs                              = $rootfs
+lxc.tty                                 = 4
+lxc.pts                                 = 1024
+#lxc.console                            = /var/log/lxc/$name.console
+
+## Capabilities
+lxc.cap.drop                            = sys_admin
+
+# uncomment the next line to run the container unconfined:
+#lxc.aa_profile = unconfined
+
+## Devices
+#lxc.cgroup.devices.allow               = a
+lxc.cgroup.devices.deny                 = a
+# /dev/null
+lxc.cgroup.devices.allow                = c 1:3 rwm
+# /dev/zero
+lxc.cgroup.devices.allow                = c 1:5 rwm
+# /dev/tty[1-4] 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
+# /dev/rtc
+lxc.cgroup.devices.allow                = c 254:0 rwm
+
+## Limits
+#lxc.cgroup.cpu.shares                  = 1024
+#lxc.cgroup.cpuset.cpus                 = 0
+#lxc.cgroup.memory.limit_in_bytes       = 256M
+#lxc.cgroup.memory.memsw.limit_in_bytes = 1G
+
+## Filesystem
+lxc.mount.entry                         = proc proc proc nodev,noexec,nosuid 0 0
+lxc.mount.entry                         = sysfs sys sysfs defaults,ro 0 0
+#lxc.mount.entry                        = /srv/$name srv/$name none defaults,bind 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 -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
+
+rootfs=$path/rootfs
+
+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
+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.7.5-3ubuntu63/templates/lxc-fedora b/lxc/0.7.5-3ubuntu63/templates/lxc-fedora
new file mode 100755 (executable)
index 0000000..ca9df0d
--- /dev/null
@@ -0,0 +1,417 @@
+#!/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
+    cat <<EOF >> $config_path/config
+lxc.utsname = $name
+lxc.tty = 4
+lxc.pts = 1024
+lxc.rootfs = $rootfs_path
+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
+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.7.5-3ubuntu63/templates/lxc-opensuse b/lxc/0.7.5-3ubuntu63/templates/lxc-opensuse
new file mode 100755 (executable)
index 0000000..5e39713
--- /dev/null
@@ -0,0 +1,371 @@
+#!/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=11.4
+
+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
+
+    # patch boot script, no longer needed in openSUSE 12.1 / SLE11-SP2
+    patch --quiet -d $rootfs/etc/init.d/ << EOF
+--- boot.orig  2011-05-26 16:03:07.000000000 +0200
++++ boot       2011-05-26 16:03:19.000000000 +0200
+@@ -98,12 +98,12 @@
+     echo "***************************************************************"
+     /sbin/halt -f
+     fi
+-    echo -n "Mounting devtmpfs at /dev"
+-    mount -n -t devtmpfs -o mode=0755 devtmpfs /dev
+-    rc_status -v -r
++#    echo -n "Mounting devtmpfs at /dev"
++#    mount -n -t devtmpfs -o mode=0755 devtmpfs /dev
++#    rc_status -v -r
+ fi
+
+-cp -axT --remove-destination /lib/udev/devices /dev
++#cp -axT --remove-destination /lib/udev/devices /dev
+
+ if test -d /sys/kernel/debug -a "$HAVE_DEBUGFS" = "1" ; then
+     mount -n -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1
+EOF
+    cat <<EOF >> $rootfs/etc/sysconfig/boot
+# disable root fsck
+ROOTFS_FSCK="0"
+ROOTFS_BLKDEV="/dev/null"
+EOF
+
+
+    # remove pointless services in a container
+    insserv -r -f -p $rootfs/etc/init.d boot.udev boot.udev_retry boot.md boot.lvm boot.loadmodules boot.device-mapper boot.clock boot.swap boot.klog
+
+    echo "Please change root-password !"
+    echo "root:root" | chroot $rootfs chpasswd
+
+    return 0
+}
+
+download_opensuse()
+{
+    cache=$1
+    arch=$2
+
+    # 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/dev"
+    mknod -m 666 $cache/partial-$arch/dev/null c 1 3
+    mknod -m 666 $cache/partial-$arch/dev/zero c 1 5
+    zypper --quiet --root $cache/partial-$arch --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss
+    zypper --quiet --root $cache/partial-$arch --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update
+    zypper --quiet --root $cache/partial-$arch --non-interactive --gpg-auto-import-keys in --auto-agree-with-licenses -t pattern base
+    zypper --quiet --root $cache/partial-$arch --non-interactive --gpg-auto-import-keys in +lxc -kbd -patterns-openSUSE-base
+    if [ $? -ne 0 ]; then
+       echo "Failed to download the rootfs, aborting."
+       return 1
+    fi
+
+    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
+
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+
+lxc.tty = 4
+lxc.pts = 1024
+lxc.rootfs = $rootfs
+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
+
+rootfs=$path/rootfs
+
+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.7.5-3ubuntu63/templates/lxc-sshd b/lxc/0.7.5-3ubuntu63/templates/lxc-sshd
new file mode 100755 (executable)
index 0000000..b0f566f
--- /dev/null
@@ -0,0 +1,227 @@
+#!/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
+
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+lxc.pts = 1024
+lxc.rootfs = $rootfs
+# 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/lib/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 /usr/lib/lxc/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 /usr/lib/lxc/lxc-init -- /usr/sbin/sshd
+    exit 1
+fi
+
+if [ -z "$path" ]; then
+    echo "'path' parameter is required"
+    exit 1
+fi
+
+rootfs=$path/rootfs
+
+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.7.5-3ubuntu63/templates/lxc-ubuntu b/lxc/0.7.5-3ubuntu63/templates/lxc-ubuntu
new file mode 100755 (executable)
index 0000000..b2e30d1
--- /dev/null
@@ -0,0 +1,694 @@
+#!/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
+}
+
+download_ubuntu()
+{
+    cache=$1
+    arch=$2
+    release=$3
+
+    packages=vim,ssh
+    echo "installing packages: $packages"
+
+    # 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
+    ret=$?
+    rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
+
+    if [ $ret -ne 0 ]; then
+        echo "Failed to upgrade the cache"
+        return 1
+    fi
+
+    mv "$1/partial-$arch" "$1/rootfs-$arch"
+    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
+
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+
+lxc.devttydir =$ttydir
+lxc.tty = 4
+lxc.pts = 1024
+lxc.rootfs = $rootfs
+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
+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 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
+
+rootfs=$path/rootfs
+
+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 "##"
+echo "# The default user is 'ubuntu' with password 'ubuntu'!"
+echo "# Use the 'sudo' command to run tasks as root in the container."
+echo "##"
+echo ""
diff --git a/lxc/0.7.5-3ubuntu63/templates/lxc-ubuntu-cloud b/lxc/0.7.5-3ubuntu63/templates/lxc-ubuntu-cloud
new file mode 100755 (executable)
index 0000000..ba33923
--- /dev/null
@@ -0,0 +1,378 @@
+#!/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
+
+    cat <<EOF >> $path/config
+lxc.utsname = $name
+
+lxc.tty = 4
+lxc.pts = 1024
+lxc.rootfs = $rootfs
+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
+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|maverick|natty|oneiric|precise)
+            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 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" -a ! -f "$userdata" ]; then
+    echo "Userdata does not exist"
+    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
+
+rootfs=$path/rootfs
+
+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`
+
+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
+    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
+}
+
+mkdir -p /var/lock/subsys/
+(
+    flock -x 200
+
+    cd $cache
+    if [ $flushcache -eq 1 ]; then
+        echo "Clearing the cached images"
+        rm -f $filename
+    fi
+
+    if [ ! -f $filename ]; then
+       wget $url2 || build_root_tgz $url1 $filename
+    fi
+
+    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
+
+       rm $rootfs/etc/hostname
+
+       if [ $locales -eq 1 ]; then
+               cp /usr/lib/locale/locale-archive $rootfs/usr/lib/locale/locale-archive
+       fi
+
+
+       if [ -n "$auth_key" -a -f "$auth_key" ]; then
+               u_path="/home/ubuntu/.ssh"
+               root_u_path="$rootfs/$u_path"
+               mkdir -p $root_u_path
+               cp $auth_key "$root_u_path/authorized_keys"
+               chroot $rootfs chown -R ubuntu: "$u_path"
+
+               echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys"
+       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}')
+EOF
+       fi
+
+       chroot $rootfs /usr/sbin/usermod -U ubuntu
+       echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
+       echo "Please login as user ubuntu with password ubuntu."
+
+   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