lxc-ubuntu-cloud.in revision 65d8ae9c4a66f5ca85289c02dc06d63261c84619
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#!/bin/bash
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser# template script for generating ubuntu container for LXC based on released
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser# cloud images.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Copyright © 2012 Serge Hallyn <serge.hallyn@canonical.com>
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# This program is free software; you can redistribute it and/or modify
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# it under the terms of the GNU General Public License version 2, as
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# published by the Free Software Foundation.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# This program is distributed in the hope that it will be useful,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# but WITHOUT ANY WARRANTY; without even the implied warranty of
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# GNU General Public License for more details.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# You should have received a copy of the GNU General Public License along
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# with this program; if not, write to the Free Software Foundation, Inc.,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynset -e
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserSTATE_DIR="@LOCALSTATEDIR@"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserHOOK_DIR="@LXCHOOKDIR@"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserCLONE_HOOK_FN="$HOOK_DIR/ubuntu-cloud-prep"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -r /etc/default/lxc ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn . /etc/default/lxc
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynam_in_userns() {
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; }
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn echo yes
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn}
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynin_userns=0
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn[ $(am_in_userns) = "yes" ] && in_userns=1
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncopy_configuration()
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn{
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn path=$1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn rootfs=$2
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn name=$3
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=$4
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn release=$5
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ $arch = "i386" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch="i686"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn # if there is exactly one veth network entry, make sure it has an
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn # associated hwaddr.
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
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn fi
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cat <<EOF >> $path/config
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graberlxc.mount = $path/fstab
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graberlxc.pivotdir = lxc_putold
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graberlxc.devttydir =$ttydir
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.tty = 4
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.pts = 1024
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graberlxc.utsname = $name
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.arch = $arch
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallynlxc.cap.drop = sys_module mac_admin mac_override sys_time
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber# When using LXC with apparmor, uncomment the next line to run unconfined:
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber#lxc.aa_profile = unconfined
9313e1e628160ca64f9e7fcec6500056c9a0725fStéphane Graber
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallyn# To support container nesting on an Ubuntu host, uncomment next two lines:
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallyn#lxc.aa_profile = lxc-container-default-with-nesting
b85ab7989ebe24629267048cb269b278eeb50490Serge Hallyn#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserlxc.hook.clone = ${CLONE_HOOK_FN}
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.deny = a
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Allow any mknod (but not using the node)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c *:* m
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = b *:* m
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# /dev/null and zero
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 1:3 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 1:5 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# consoles
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 5:1 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 5:0 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# /dev/{,u}random
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 1:9 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 1:8 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 136:* rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 5:2 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# rtc
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallynlxc.cgroup.devices.allow = c 254:0 rm
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber# fuse
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 10:229 rwm
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber# tun
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 10:200 rwm
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber# full
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 1:7 rwm
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber# hpet
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 10:228 rwm
a2abaa9ec60a8967611e8c8905698bd01bde5861Stéphane Graber# kvm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynlxc.cgroup.devices.allow = c 10:232 rwm
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge HallynEOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cat <<EOF > $path/fstab
80a881b232b8955b85b360d4def99e6e680ff61bSerge Hallynproc proc proc nodev,noexec,nosuid 0 0
80a881b232b8955b85b360d4def99e6e680ff61bSerge Hallynsysfs sys sysfs defaults 0 0
6f259716e75552cf46ee5125bdbd21e34456d0c0Serge Hallyn/sys/fs/fuse/connections sys/fs/fuse/connections none bind 0 0
6f259716e75552cf46ee5125bdbd21e34456d0c0Serge Hallyn/sys/kernel/debug sys/kernel/debug none bind 0 0
6f259716e75552cf46ee5125bdbd21e34456d0c0Serge Hallyn/sys/kernel/security sys/kernel/security none bind 0 0
bf7d76cf3ae180820c0a29e0bfbaa97c20ce6a3dSerge HallynEOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn # unprivileged user can't mknod these. One day we may allow
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn # that in the kernel, but not right now. So let's just bind
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn # mount the files from the host.
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn if [ $in_userns -eq 1 ]; then
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn for dev in null tty urandom console; do
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn touch $rootfs/dev/$dev
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn echo "/dev/$dev dev/$dev none bind 0 0" >> $path/fstab
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn done
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn fi
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn
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.
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber mv $rootfs/dev/shm $rootfs/dev/shm.bak
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn ln -s /run/shm $rootfs/dev/shm
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn fi
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return 0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn}
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynusage()
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn{
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cat <<EOF
4759162d078d86628956cae4846c6efccf548e67Serge HallynLXC Container configuration for Ubuntu Cloud images.
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
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
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -a | --arch ]: Arhcitecture of container, defaults to host arcitecture
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -T | --tarball ]: Location of tarball
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn[ -d | --debug ]: Run with 'set -x' to debug errors
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn[ -s | --stream]: Use specified stream rather than 'released'
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserAdditionally, clone hooks can be passed through (ie, --userdata). For those,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosersee:
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser $CLONE_HOOK_FN --help
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge HallynEOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return 0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn}
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynoptions=$(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: -- "$@")
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ $? -ne 0 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn usage $(basename $0)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyneval set -- "$options"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser# default release is precise, or the systems release if recognized
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserrelease=precise
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -f /etc/lsb-release ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn . /etc/lsb-release
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser rels=$(ubuntu-distro-info --supported 2>/dev/null) ||
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser rels="lucid natty oneiric precise quantal raring saucy"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser for r in $rels; do
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser [ "$DISTRIB_CODENAME" = "$r" ] && release="$r"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser done
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Code taken from debootstrap
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=`/usr/bin/dpkg --print-architecture`
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynelif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=`/usr/bin/udpkg --print-architecture`
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynelse
ed4616b1cfbc84dd01caa8546d813e8c5d482921Christian Bühler arch=$(uname -m)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ "$arch" = "i686" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch="i386"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn elif [ "$arch" = "x86_64" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch="amd64"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn elif [ "$arch" = "armv7l" ]; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn # note: arm images don't exist before oneiric; are called armhf in
b8bced69a80a8be95fdbbb6b4e9ad7fa85464b1eSerge Hallyn # precise 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.
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber arch="armhf"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyndebug=0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynhostarch=$arch
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncloud=0
4759162d078d86628956cae4846c6efccf548e67Serge Hallynlocales=1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynflushcache=0
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallynstream="released"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosercloneargs=()
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynwhile true
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyndo
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn case "$1" in
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -h|--help) usage $0 && exit 0;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -p|--path) path=$2; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -n|--name) name=$2; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -F|--flush-cache) flushcache=1; shift 1;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -r|--release) release=$2; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -a|--arch) arch=$2; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn -T|--tarball) tarball=$2; shift 2;;
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn -d|--debug) debug=1; shift 1;;
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn -s|--stream) stream=$2; shift 2;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser --rootfs) rootfs=$2; shift 2;;
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;;
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 ;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn *) break ;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn esac
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyndone
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosercloneargs=( "--name=$name" "${cloneargs[@]}" )
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallynif [ $debug -eq 1 ]; then
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn set -x
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallynfi
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ "$arch" == "i686" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=i386
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberif [ $arch != "i386" -a $arch != "amd64" -a $arch != "armhf" -a $arch != "armel" ]; then
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber echo "Only i386, amd64, armel and armhf are supported by the ubuntu cloud template."
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberif [ $hostarch != "i386" -a $hostarch != "amd64" -a $hostarch != "armhf" -a $hostarch != "armel" ]; then
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber echo "Only i386, amd64, armel and armhf are supported as host."
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber exit 1
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberfi
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberif [ $hostarch = "amd64" -a $arch != "amd64" -a $arch != "i386" ]; then
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber echo "can't create $arch container on $hostarch"
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber exit 1
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberfi
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberif [ $hostarch = "i386" -a $arch != "i386" ]; then
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber echo "can't create $arch container on $hostarch"
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber exit 1
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberfi
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graberif [ $hostarch = "armhf" -o $hostarch = "armel" ] && \
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber [ $arch != "armhf" -a $arch != "armel" ]; then
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber echo "can't create $arch container on $hostarch"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallynif [ "$stream" != "daily" -a "$stream" != "released" ]; then
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn echo "Only 'daily' and 'released' streams are supported"
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn exit 1
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallynfi
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -z "$path" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "'path' parameter is required"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ "$(id -u)" != "0" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "This script should be run as 'root'"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn# detect rootfs
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallynconfig="$path/config"
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynif [ -z "$rootfs" ]; then
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn else
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn rootfs=$path/rootfs
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn fi
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyntype ubuntu-cloudimg-query
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyntype wget
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# determine the url, tarball, and directory names
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# download if needed
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosercache="$STATE_DIR/cache/lxc/cloud-$release"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynmkdir -p $cache
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
4759162d078d86628956cae4846c6efccf548e67Serge Hallynif [ -n "$tarball" ]; then
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser url2="$tarball"
4759162d078d86628956cae4846c6efccf548e67Serge Hallynelse
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'`
4759162d078d86628956cae4846c6efccf548e67Serge Hallynfi
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfilename=`basename $url2`
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynwgetcleanup()
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn{
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser rm -f $filename
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn}
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallynbuildcleanup()
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn{
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn cd $rootfs
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn umount -l $cache/$xdir || true
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rm -rf $cache
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn}
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn# if the release doesn't have a *-rootfs.tar.gz, then create one from the
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn# a tarball from the mounted image.
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallynbuild_root_tgz()
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn{
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn url=$1
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn filename=$2
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn xdir=`mktemp -d -p .`
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn tarname=`basename $url`
edd3810e951ec1b20af761955e6100ab75a66534Serge Hallyn imgname="$release-*-cloudimg-$arch.img"
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap buildcleanup EXIT SIGHUP SIGINT SIGTERM
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rm -f $tarname
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "Downloading cloud image from $url"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn wget $url || { echo "Couldn't find cloud image $url."; exit 1; }
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn fi
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "Creating new cached cloud image rootfs"
edd3810e951ec1b20af761955e6100ab75a66534Serge Hallyn tar --wildcards -zxf $tarname $imgname
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn mount -o loop $imgname $xdir
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn (cd $xdir; tar zcf ../$filename .)
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn umount $xdir
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rm -f $tarname $imgname
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rmdir $xdir
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "New cloud image cache created"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn trap EXIT
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGHUP
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGINT
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGTERM
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn}
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyndo_extract_rootfs() {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cd $cache
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ $flushcache -eq 1 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "Clearing the cached images"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn rm -f $filename
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ ! -f $filename ]; then
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser wget $url2 || build_root_tgz $url1 $filename
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap EXIT
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGHUP
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGINT
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGTERM
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "Extracting container rootfs"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn mkdir -p $rootfs
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cd $rootfs
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn tar -zxf $cache/$filename
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn}
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynif [ -n "$tarball" ]; then
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn do_extract_rootfs
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynelse
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser mkdir -p "$STATE_DIR/lock/subsys/"
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn (
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn flock -x 200
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn do_extract_rootfs
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser ) 200>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud"
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyncopy_configuration $path $rootfs $name $arch $release
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynecho "Container $name created."
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynexit 0
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser# vi: ts=4 expandtab