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@"
3a5495cf2f6c1806f5a91d699448b15b510f146ePo-Hsu LinKNOWN_RELEASES="precise trusty xenial yakkety zesty"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserskip_arch_check=${UCTEMPLATE_SKIP_ARCH_CHECK:-0}
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber# Make sure the usual locations are in PATH
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graberexport PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
207bf0e475f1dc6e9a2dac2cee3a209b56427855Stéphane Graber
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
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber # 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
bf7d76cf3ae180820c0a29e0bfbaa97c20ce6a3dSerge HallynEOF
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ## 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
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber # 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
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe . /etc/sysconfig/clock
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber 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
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
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
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'
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
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: -- "$@")
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynif [ $? -ne 0 ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn usage $(basename $0)
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn exit 1
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyneval set -- "$options"
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynmapped_uid=-1
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynmapped_gid=-1
f8b2a49ce0bb7ce66d0c902b5976a48e49f754b2Stéphane Graber# default release is trusty, or the systems release if recognized
f8b2a49ce0bb7ce66d0c902b5976a48e49f754b2Stéphane Graberrelease=trusty
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
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.
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
4a3110456051b5b018a73507ba4f56adb81006eeStéphane Graber -h|--help) usage $0 && exit 1;;
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;;
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;;
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn --mapped-uid) mapped_uid=$2; shift 2;;
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn --mapped-gid) mapped_gid=$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
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäeif [ "$arch" = "i686" ]; then
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn arch=i386
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moserif [ "$skip_arch_check" = "0" ]; then
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser case "$hostarch:$arch" in
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser $arch:$arch) : ;; # the host == container
d46417540f61ffb93344f3d338340588bf118ab4Stéphane Graber amd64:i386) :;; # supported "cross"
d46417540f61ffb93344f3d338340588bf118ab4Stéphane Graber arm64:arm*) :;; # supported "cross"
d46417540f61ffb93344f3d338340588bf118ab4Stéphane Graber armel:armhf) :;; # supported "cross"
d46417540f61ffb93344f3d338340588bf118ab4Stéphane Graber armhf:armel) :;; # supported "cross"
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser *) echo "cannot create '$arch' container on hostarch '$hostarch'";
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser exit 1;;
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser esac
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
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"
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
853d58fdf5af0960b7b6edc9dea0fadddb8535f1Elan Ruusamäe rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config)
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
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Carter# Allow the cache base to be set by environment variable
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Cartercache=${LXC_CACHE_PATH:-"$STATE_DIR/cache/lxc"}/cloud-$release
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graberif [ $in_userns -eq 1 ]; then
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Carter STATE_DIR="$HOME/.cache/lxc"
6dc6f80bfd7cb169948f2ef9a95dcf6d2edee853Kevin Carter cache=${LXC_CACHE_PATH:-"$STATE_DIR"}/cloud-$release
9cde0368fbbfa61add2e73f8ccd5b00c1b0f2e08Stéphane Graberfi
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynmkdir -p $cache
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovif [ "$stream" = "tryreleased" ]; then
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov stream=released
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov ubuntu-cloudimg-query $release $stream $arch 1>/dev/null 2>/dev/null || stream=daily
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkovfi
4b954f12173c382f7104a0e9464fa66dd3cade35Dimitri John Ledkov
4759162d078d86628956cae4846c6efccf548e67Serge Hallynif [ -n "$tarball" ]; then
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser url2="$tarball"
4759162d078d86628956cae4846c6efccf548e67Serge Hallynelse
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'"
4a3110456051b5b018a73507ba4f56adb81006eeStéphane Graber exit 1
ad3f14ab58ec91ff11d0dcf2cbd5f47f02935344Scott Moser fi
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin if [ "$release" = "precise" ] || [ "$release" = "trusty" ]; then
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/' -e 's/.tar.gz/.tar.xz/'`
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin else
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin url2=`echo $url1 | sed -e 's/.tar.gz/.squashfs/'`
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin fi
4759162d078d86628956cae4846c6efccf548e67Serge Hallynfi
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynfilename=`basename $url2`
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallynwgetcleanup()
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn{
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser rm -f $filename
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn}
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge 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
27c278a76931bfc4660caa85d1942ca91c86e0bfStéphane Graber wget $url2
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
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin if [ "${filename##*.}" = "squashfs" ]; then
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin unsquashfs -n -f -d "$rootfs" "$cache/$filename"
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn else
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin if [ $in_userns -eq 1 ]; then
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin tar --anchored --exclude="dev/*" --numeric-owner -xpf "$cache/$filename"
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin mkdir -p $rootfs/dev/pts/
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin else
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin tar --numeric-owner -xpf "$cache/$filename"
26312a76c8a1078976a5b391ece4f650a6f1b000Po-Hsu Lin fi
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn fi
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 (
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe flock -x 9
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn do_extract_rootfs
17abf2784de1047fb2904ff130ee5efe4ea7b598Elan Ruusamäe ) 9>"$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
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynif [ $mapped_uid -ne -1 ]; then
c01c25fcdd1e0cacad8075bcfcef4c8e8d4b8cb6Stéphane Graber chown $mapped_uid $path/config
c01c25fcdd1e0cacad8075bcfcef4c8e8d4b8cb6Stéphane Graber chown -R $mapped_uid $STATE_DIR
c01c25fcdd1e0cacad8075bcfcef4c8e8d4b8cb6Stéphane Graber chown -R $mapped_uid $cache
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallynfi
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynif [ $mapped_gid -ne -1 ]; then
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn chgrp $mapped_gid $path/config
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn chgrp -R $mapped_gid $STATE_DIR
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallyn chgrp -R $mapped_gid $cache
2133f58c66ab7627a4159fafbb75106c556b014dSerge Hallynfi
57d116ab501594c2e50ab45f1cf2fae48c5eab09Serge Hallyn
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynecho "Container $name created."
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallynexit 0
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser
b942e67226af9e690bd63ac440b99aedb6becbb3Scott Moser# vi: ts=4 expandtab