lxc-ubuntu-cloud.in revision 2b142295afb3cac8c4be2a233e51ab5a9f7e10e9
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# template script for generating ubuntu container for LXC based on released
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen# cloud images.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# Copyright © 2012 Serge Hallyn <serge.hallyn@canonical.com>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# This library is free software; you can redistribute it and/or
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# modify it under the terms of the GNU Lesser General Public
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainen# License as published by the Free Software Foundation; either
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# version 2.1 of the License, or (at your option) any later version.
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# This library is distributed in the hope that it will be useful,
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# but WITHOUT ANY WARRANTY; without even the implied warranty of
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# Lesser General Public License for more details.
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen# You should have received a copy of the GNU Lesser General Public
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# License along with this library; if not, write to the Free Software
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen [ -e /proc/self/uid_map ] || { echo no; return; }
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; }
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map)
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen [ "$line" = "0 0 4294967295" ] && { echo no; return; }
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen # if there is exactly one veth network entry, make sure it has an
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if [ $nics -eq 1 ]; then
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen sed -i -e "/lxc.network/{w ${path}/config-network" -e "d}" $path/config
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" ]; then
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" >> $path/config
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" ]; then
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" >> $path/config
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" >> $path/config
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "# Container specific configuration" >> $path/config
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenlxc.mount = $path/fstab
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenlxc.utsname = $name
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainenlxc.arch = $arch
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ## Re-add the previously removed network config
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen echo "# Network configuration" >> $path/config
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if [ -f /etc/timezone ]; then
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen elif [ -f /etc/sysconfig/clock ]; then
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen echo "Timezone in container is not configured. Adjust it manually."
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # rmdir /dev/shm for containers that have /run/shm
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # get bind mounted to the host's /run/shm. So try to rmdir
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # it, and in case that fails move it out of the way.
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen # NOTE: This can only be removed once 12.04 goes out of support
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo SirainenLXC Container configuration for Ubuntu Cloud images.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo SirainenGeneric Options
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen[ -r | --release <release> ]: Release name of container, defaults to host
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen[ --rootfs <path> ]: Path in which rootfs will be placed
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen[ -a | --arch ]: Arhcitecture of container, defaults to host architecture
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen[ -T | --tarball ]: Location of tarball
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen[ -d | --debug ]: Run with 'set -x' to debug errors
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen[ -s | --stream]: Use specified stream rather than 'released'
3697080532ccd9f51fac108be6079b616c7a2ddfTimo SirainenAdditionally, clone hooks can be passed through (ie, --userdata). For those,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen $CLONE_HOOK_FN --help
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenoptions=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata:,mapped-uid: -- "$@")
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen# default release is precise, or the systems release if recognized
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen rels=$(ubuntu-distro-info --supported 2>/dev/null) ||
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen rels="lucid natty oneiric precise quantal raring saucy"
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen [ "$DISTRIB_CODENAME" = "$r" ] && release="$r"
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen# Code taken from debootstrap
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenif [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenelif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen # note: arm images don't exist before oneiric; are called armhf in
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen # precise and later; and are not supported by the query, so we don't actually
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen # support them yet (see check later on). When Query2 is available,
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen # we'll use that to enable arm images.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen -L|--no?locales) cloneargs[${#cloneargs[@]}]="--no-locales"; shift 1;;
7889c9f65e23c83fc31cecf304cab4ab070d6aa1Timo Sirainen -i|--hostid) cloneargs[${#cloneargs[@]}]="--hostid=$2"; shift 2;;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen -u|--userdata) cloneargs[${#cloneargs[@]}]="--userdata=$2"; shift 2;;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen --) shift 1; break ;;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenecho "mapped_uid is .$mapped_uid."
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenif [ $arch != "i386" -a $arch != "amd64" -a $arch != "armhf" -a $arch != "armel" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "Only i386, amd64, armel and armhf are supported by the ubuntu cloud template."
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenif [ $hostarch != "i386" -a $hostarch != "amd64" -a $hostarch != "armhf" -a $hostarch != "armel" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "Only i386, amd64, armel and armhf are supported as host."
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenif [ $hostarch = "amd64" -a $arch != "amd64" -a $arch != "i386" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "can't create $arch container on $hostarch"
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainenif [ $hostarch = "i386" -a $arch != "i386" ]; then
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen echo "can't create $arch container on $hostarch"
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenif [ $hostarch = "armhf" -o $hostarch = "armel" ] && \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen [ $arch != "armhf" -a $arch != "armel" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "can't create $arch container on $hostarch"
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenif [ "$stream" != "daily" -a "$stream" != "released" ]; then
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen echo "Only 'daily' and 'released' streams are supported"
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenif [ -z "$path" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "'path' parameter is required"
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen echo "This script should be run as 'root'"
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen# detect rootfs
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenif [ -z "$rootfs" ]; then
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
3342badd8c69adff34db589fb0a221ace5996212Timo Sirainen# determine the url, tarball, and directory names
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen# download if needed
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenif [ -n "$tarball" ]; then
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'`
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen# if the release doesn't have a *-rootfs.tar.gz, then create one from the
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen# a tarball from the mounted image.
2ebfb5c0608e2323b73271208f4036a7ea7d7f3aTimo Sirainen if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen wget $url || { echo "Couldn't find cloud image $url."; exit 1; }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen (cd $xdir; tar --numeric-owner -cpzf "../$filename" .)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if [ $flushcache -eq 1 ]; then
41bb0aa8e357876bc9a1916a37c9e3e78e5f8185Timo Sirainen if [ ! -f $filename ]; then
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen if [ $in_userns -eq 1 ]; then
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen tar --anchored --exclude="dev/*" --numeric-owner -xpzf "$cache/$filename"
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainenif [ -n "$tarball" ]; then
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ) 200>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud"
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainencopy_configuration $path $rootfs $name $arch $release
cd5ee8630497fdbd853ef588a858b4ef619a5e03Timo Sirainen"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs"
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenecho "Container $name created."
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen# vi: ts=4 expandtab