lxc-ubuntu-cloud.in revision 27c278a76931bfc4660caa85d1942ca91c86e0bf
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#
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.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
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.
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
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
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynset -e
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserSTATE_DIR="@LOCALSTATEDIR@"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserHOOK_DIR="@LXCHOOKDIR@"
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserCLONE_HOOK_FN="$HOOK_DIR/ubuntu-cloud-prep"
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane GraberLXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott MoserKNOWN_RELEASES="precise trusty utopic vivid"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserskip_arch_check=${UCTEMPLATE_SKIP_ARCH_CHECK:-0}
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn# Make sure the usual locations are in PATH
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ -r /etc/default/lxc ]; then
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn . /etc/default/lxc
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynfi
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge 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
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynin_userns=0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn[ $(am_in_userns) = "yes" ] && in_userns=1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncopy_configuration()
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn{
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn path=$1
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn rootfs=$2
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn name=$3
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=$4
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn release=$5
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if [ $arch = "i386" ]; then
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn arch="i686"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn fi
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn # if there is exactly one veth network entry, make sure it has an
daaf41b36790bdaae855048e56ed090b17a77c97Stéphane Graber # associated hwaddr.
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn if [ $nics -eq 1 ]; then
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Sté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 fi
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn # Generate the configuration file
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## Relocate all the network config entries
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber sed -i -e "/lxc.network/{w ${path}/config-network" -e "d}" $path/config
9313e1e628160ca64f9e7fcec6500056c9a0725fStéphane Graber
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## Relocate any other config entries
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## Add all the includes
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "" >> $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 fi
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 fi
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
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## Add the container-specific config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "" >> $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 Graber cat <<EOF >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graberlxc.utsname = $name
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graberlxc.arch = $arch
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane GraberEOF
bf7d76cf3ae180820c0a29e0bfbaa97c20ce6a3dSerge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ## Re-add the previously removed network config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber echo "# Network configuration" >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber cat $path/config-network >> $path/config
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber rm $path/config-network
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn # Set initial timezone as on host
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber if [ -f /etc/timezone ]; then
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber cat /etc/timezone > $rootfs/etc/timezone
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber elif [ -f /etc/sysconfig/clock ]; then
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber . /etc/sysconfig/clock
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe echo $ZONE > $rootfs/etc/timezone
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber chroot $rootfs dpkg-reconfigure -f noninteractive tzdata
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber else
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber echo "Timezone in container is not configured. Adjust it manually."
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber fi
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber # rmdir /dev/shm for containers that have /run/shm
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber # 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.
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn # NOTE: This can only be removed once 12.04 goes out of support
5ff337745e4a705293b056ab58f6ea7a92cabbc8Stéphane Graber if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then
542939c31bb73bab55f2fd71243b98f5559597d1Stéphane Graber rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak
5ff337745e4a705293b056ab58f6ea7a92cabbc8Stéphane Graber ln -s /run/shm $rootfs/dev/shm
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn fi
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn return 0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn}
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynusage()
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn{
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn cat <<EOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge HallynLXC Container configuration for Ubuntu Cloud images.
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
4759162d078d86628956cae4846c6efccf548e67Serge HallynGeneric Options
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -r | --release <release> ]: Release name of container, defaults to host
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ --rootfs <path> ]: Path in which rootfs will be placed
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn[ -a | --arch ]: Architecture of container, defaults to host architecture
3f5f5d99b0ea1c204699b13d4a0caf4d9e745449Stéphane Graber[ -T | --tarball ]: Location of tarball
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn[ -d | --debug ]: Run with 'set -x' to debug errors
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn[ -s | --stream]: Use specified stream rather than 'tryreleased'
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser
4759162d078d86628956cae4846c6efccf548e67Serge HallynAdditionally, clone hooks can be passed through (ie, --userdata). For those,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosersee:
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser $CLONE_HOOK_FN --help
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott MoserEOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn return 0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn}
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge 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:,vendordata:,mapped-uid:,mapped-gid: -- "$@")
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynif [ $? -ne 0 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn usage $(basename $0)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyneval set -- "$options"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynmapped_uid=-1
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynmapped_gid=-1
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) ||
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser rels="$KNOWN_RELEASES"
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"
8a3c76b24d73ab8a830035e7a66400e2cc2e8334Stéphane Graber elif [ "$arch" = "aarch64" ]; then
8a3c76b24d73ab8a830035e7a66400e2cc2e8334Stéphane Graber arch="arm64"
8a3c76b24d73ab8a830035e7a66400e2cc2e8334Stéphane Graber elif [ "$arch" = "ppc64le" ]; then
8a3c76b24d73ab8a830035e7a66400e2cc2e8334Stéphane Graber arch="ppc64el"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyndebug=0
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynhostarch=$arch
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncloud=0
4759162d078d86628956cae4846c6efccf548e67Serge Hallynlocales=1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynflushcache=0
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovstream="tryreleased"
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 -V|--vendordata) cloneargs[${#cloneargs[@]}]="--vendordata=$2"; shift 2;;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;;
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;;
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn --mapped-uid) mapped_uid=$2; shift 2;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn --mapped-gid) mapped_gid=$2; shift 2;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn --) shift 1; break ;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn *) break ;;
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn esac
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyndone
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosercloneargs=( "--name=$name" "${cloneargs[@]}" )
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallynif [ $debug -eq 1 ]; then
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallyn set -x
52c8f624b5f9ef665f33a7aa80e0aa18b91daa4aSerge Hallynfi
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ "$arch" = "i686" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=i386
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserif [ "$skip_arch_check" = "0" ]; then
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser case "$hostarch:$arch" in
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser $arch:$arch) : ;; # the host == container
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser amd64:i386) :;; # supported "cross"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser arm64:arm*) :;; # supported "cross"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser armel:armhf) :;; # supported "cross"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn armhf:armel) :;; # supported "cross"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn *) echo "cannot create '$arch' container on hostarch '$hostarch'";
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov exit 1;;
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov esac
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallynfi
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallynif [ "$stream" != "daily" -a "$stream" != "released" -a "$stream" != "tryreleased" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn echo "Only 'daily' and 'released' and 'tryreleased' streams are supported"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge 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
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn echo "This script should be run as 'root'"
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn exit 1
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynfi
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn
853d58fdf5af0960b7b6edc9dea0fadddb8535f1Elan Ruusamäe# detect rootfs
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynconfig="$path/config"
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallynif [ -z "$rootfs" ]; then
1897e3bcd36af9f3fe6d3649910a9adb93e5e988Serge Hallyn if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallyn rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn else
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn rootfs=$path/rootfs
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyntype ubuntu-cloudimg-query
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Mosertype wget
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graber
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graber# determine the url, tarball, and directory names
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graber# download if needed
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graber# Allow the cache base to be set by environment variable
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncache=${LXC_CACHE_PATH:-"$STATE_DIR/cache/lxc"}/cloud-$release
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ $in_userns -eq 1 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn STATE_DIR="$HOME/.cache/lxc"
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov cache=${LXC_CACHE_PATH:-"$STATE_DIR"}/cloud-$release
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovfi
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovmkdir -p $cache
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov
4759162d078d86628956cae4846c6efccf548e67Serge Hallynif [ "$stream" = "tryreleased" ]; then
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser stream=released
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn ubuntu-cloudimg-query $release $stream $arch 1>/dev/null 2>/dev/null || stream=daily
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserfi
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserif [ -n "$tarball" ]; then
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser url2="$tarball"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserelse
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser if ! url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`; then
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn echo "There is no download available for release=$release, stream=$stream, arch=$arch"
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn [ "$stream" = "daily" ] || echo "You may try with '--stream=daily'"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn fi
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/' -e 's/.tar.gz/.tar.xz/'`
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynfi
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynfilename=`basename $url2`
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallynwgetcleanup()
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn{
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rm -f $filename
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn}
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyndo_extract_rootfs() {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn cd $cache
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if [ $flushcache -eq 1 ]; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "Clearing the cached images"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn rm -f $filename
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn fi
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if [ ! -f $filename ]; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn wget $url2
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn fi
edd3810e951ec1b20af761955e6100ab75a66534Serge Hallyn trap EXIT
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn trap SIGHUP
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn trap SIGINT
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn trap SIGTERM
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn echo "Extracting container rootfs"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn mkdir -p $rootfs
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn cd $rootfs
9c3bc32c5789b76b8c42b75d7625377d61e052c1Stéphane Graber if [ $in_userns -eq 1 ]; then
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn tar --anchored --exclude="dev/*" --numeric-owner -xpJf "$cache/$filename"
9c3bc32c5789b76b8c42b75d7625377d61e052c1Stéphane Graber mkdir -p $rootfs/dev/pts/
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn else
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn tar --numeric-owner -xpJf "$cache/$filename"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn fi
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn}
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynif [ -n "$tarball" ]; then
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn do_extract_rootfs
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynelse
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn mkdir -p "$STATE_DIR/lock/subsys/"
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn (
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn flock -x 9
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn do_extract_rootfs
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ) 9>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyncopy_configuration $path $rootfs $name $arch $release
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn"$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs"
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ $mapped_uid -ne -1 ]; then
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser chown $mapped_uid $path/config
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn chown -R $mapped_uid $STATE_DIR
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn chown -R $mapped_uid $cache
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynfi
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynif [ $mapped_gid -ne -1 ]; then
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn chgrp $mapped_gid $path/config
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn chgrp -R $mapped_gid $STATE_DIR
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn chgrp -R $mapped_gid $cache
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynecho "Container $name created."
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynexit 0
2b142295afb3cac8c4be2a233e51ab5a9f7e10e9Serge Hallyn
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn# vi: ts=4 expandtab
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn