lxc-ubuntu-cloud.in revision 3a5495cf2f6c1806f5a91d699448b15b510f146e
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser# template script for generating ubuntu container for LXC based on released
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser# cloud images.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Copyright © 2012 Serge Hallyn <serge.hallyn@canonical.com>
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# This library is free software; you can redistribute it and/or
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# modify it under the terms of the GNU Lesser General Public
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# License as published by the Free Software Foundation; either
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# version 2.1 of the License, or (at your option) any later version.
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# This library is distributed in the hope that it will be useful,
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# but WITHOUT ANY WARRANTY; without even the implied warranty of
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# Lesser General Public License for more details.
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# You should have received a copy of the GNU Lesser General Public
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# License along with this library; if not, write to the Free Software
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3a5495cf2f6c1806f5a91d699448b15b510f146ePo-Hsu LinKNOWN_RELEASES="precise trusty xenial yakkety zesty"
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber# Make sure the usual locations are in PATH
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graberexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn [ -e /proc/self/uid_map ] || { echo no; return; }
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; }
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map)
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn [ "$line" = "0 0 4294967295" ] && { echo no; return; }
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn # if there is exactly one veth network entry, make sure it has an
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn if [ $nics -eq 1 ]; then
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber 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
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber sed -i -e "/lxc.network/{w ${path}/config-network" -e "d}" $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "# Common configuration" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" ]; then
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" ]; then
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "# Container specific configuration" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graberlxc.utsname = $name
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graberlxc.arch = $arch
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## Re-add the previously removed network config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "# Network configuration" >> $path/config
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber if [ -f /etc/timezone ]; then
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber elif [ -f /etc/sysconfig/clock ]; then
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber echo "Timezone in container is not configured. Adjust it manually."
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber # rmdir /dev/shm for containers that have /run/shm
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn # get bind mounted to the host's /run/shm. So try to rmdir
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn # it, and in case that fails move it out of the way.
5ff337745e4a705293b056ab58f6ea7a92cabbc8Stéphane Graber # NOTE: This can only be removed once 12.04 goes out of support
68c36a303f402b52f94067d3da7b168e274001a7Serge Hallyn if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then
5ff337745e4a705293b056ab58f6ea7a92cabbc8Stéphane Graber rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak
4759162d078d86628956cae4846c6efccf548e67Serge HallynLXC Container configuration for Ubuntu Cloud images.
4759162d078d86628956cae4846c6efccf548e67Serge HallynGeneric Options
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -r | --release <release> ]: Release name of container, defaults to host
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn[ --rootfs <path> ]: Path in which rootfs will be placed
3f5f5d99b0ea1c204699b13d4a0caf4d9e745449Stéphane Graber[ -a | --arch ]: Architecture of container, defaults to host architecture
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -T | --tarball ]: Location of tarball
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn[ -d | --debug ]: Run with 'set -x' to debug errors
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser[ -s | --stream]: Use specified stream rather than 'tryreleased'
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserAdditionally, clone hooks can be passed through (ie, --userdata). For those,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser $CLONE_HOOK_FN --help
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moseroptions=$(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:,vendordata:,mapped-uid:,mapped-gid: -- "$@")
f8b2a49ce0bb7ce66d0c902b5976a48e49f754b2Stéphane Graber# default release is trusty, or the systems release if recognized
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser rels=$(ubuntu-distro-info --supported 2>/dev/null) ||
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Code taken from debootstrap
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynelif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn # note: arm images don't exist before oneiric; are called armhf in
f8b2a49ce0bb7ce66d0c902b5976a48e49f754b2Stéphane Graber # trusty and later; and are not supported by the query, so we don't actually
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn # support them yet (see check later on). When Query2 is available,
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn # we'll use that to enable arm images.
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -L|--no?locales) cloneargs[${#cloneargs[@]}]="--no-locales"; shift 1;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -i|--hostid) cloneargs[${#cloneargs[@]}]="--hostid=$2"; shift 2;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -u|--userdata) cloneargs[${#cloneargs[@]}]="--userdata=$2"; shift 2;;
5d066f24e65ef482cdfee241ce65e060d1652efcScott Moser -V|--vendordata) cloneargs[${#cloneargs[@]}]="--vendordata=$2"; shift 2;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn --) shift 1; break ;;
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser *) echo "cannot create '$arch' container on hostarch '$hostarch'";
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovif [ "$stream" != "daily" -a "$stream" != "released" -a "$stream" != "tryreleased" ]; then
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov echo "Only 'daily' and 'released' and 'tryreleased' streams are supported"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -z "$path" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "'path' parameter is required"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "This script should be run as 'root'"
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn# detect rootfs
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynif [ -z "$rootfs" ]; then
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
853d58fdf5af0960b7b6edc9dea0fadddb8535f1Elan Ruusamäe rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# determine the url, tarball, and directory names
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# download if needed
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Carter# Allow the cache base to be set by environment variable
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Cartercache=${LXC_CACHE_PATH:-"$STATE_DIR/cache/lxc"}/cloud-$release
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Carter cache=${LXC_CACHE_PATH:-"$STATE_DIR"}/cloud-$release
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov ubuntu-cloudimg-query $release $stream $arch 1>/dev/null 2>/dev/null || stream=daily
4759162d078d86628956cae4846c6efccf548e67Serge Hallynif [ -n "$tarball" ]; then
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser if ! url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`; then
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser echo "There is no download available for release=$release, stream=$stream, arch=$arch"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser [ "$stream" = "daily" ] || echo "You may try with '--stream=daily'"
27c278a76931bfc4660caa85d1942ca91c86e0bfStéphane Graber url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/' -e 's/.tar.gz/.tar.xz/'`
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ $flushcache -eq 1 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ ! -f $filename ]; then
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn if [ $in_userns -eq 1 ]; then
f8b2a49ce0bb7ce66d0c902b5976a48e49f754b2Stéphane Graber tar --anchored --exclude="dev/*" --numeric-owner -xpf "$cache/$filename"
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynif [ -n "$tarball" ]; then
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyncopy_configuration $path $rootfs $name $arch $release
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynecho "Container $name created."
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser# vi: ts=4 expandtab