lxc-ubuntu.in revision 1897e3bcd36af9f3fe6d3649910a9adb93e5e988
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# template script for generating ubuntu container for LXC
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# This script consolidates and extends the existing lxc ubuntu scripts
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# Copyright � 2011 Serge Hallyn <serge.hallyn@canonical.com>
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# Copyright � 2010 Wilhelm Meier
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# This program is free software; you can redistribute it and/or modify
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# it under the terms of the GNU General Public License version 2, as
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# published by the Free Software Foundation.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# This program is distributed in the hope that it will be useful,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# but WITHOUT ANY WARRANTY; without even the implied warranty of
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# GNU General Public License for more details.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# You should have received a copy of the GNU General Public License along
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# with this program; if not, write to the Free Software Foundation, Inc.,
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# This file describes the network interfaces available on your system
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi# and how to activate them. For more information, see interfaces(5).
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi# The loopback network interface
8c3a756ed4cf22f9fdab5f95d067321e6ddcc425KATOH Yasufumiiface lo inet loopback
8c3a756ed4cf22f9fdab5f95d067321e6ddcc425KATOH Yasufumiiface eth0 inet dhcp
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi127.0.0.1 localhost
8adef7614d4340b4ee44a4441fadd530f48515edKATOH Yasufumi127.0.1.1 $hostname
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi# The following lines are desirable for IPv6 capable hosts
8c3a756ed4cf22f9fdab5f95d067321e6ddcc425KATOH Yasufumi::1 ip6-localhost ip6-loopback
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumife00::0 ip6-localnet
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumiff00::0 ip6-mcastprefix
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumiff02::1 ip6-allnodes
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumiff02::2 ip6-allrouters
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi # remove jobs for consoles 5 and 6 since we only create 4 consoles in
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi chroot $rootfs useradd --create-home -s /bin/bash ubuntu
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
8adef7614d4340b4ee44a4441fadd530f48515edKATOH Yasufumi # make sure we have the current locale defined in the container
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ -z "$LANG" ] || echo $LANG | grep -E -q "^C(\..+)*$"; then
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi chroot $rootfs update-locale LANG=en_US.UTF-8
adf4b4083369a8bb7ed3c2ce3dd85dcaed7323c4KATOH Yasufumi if [ -x $rootfs@LOCALSTATEDIR@/lib/dpkg/info/openssh-server.postinst ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi mv $rootfs/etc/init/ssh.conf $rootfs/etc/init/ssh.conf.disabled
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi chroot $rootfs @LOCALSTATEDIR@/lib/dpkg/info/openssh-server.postinst configure
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi mv $rootfs/etc/init/ssh.conf.disabled $rootfs/etc/init/ssh.conf
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# finish setting up the user in the container by injecting ssh key and
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# adding sudo group membership.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# passed-in user is either 'ubuntu' or the user to bind in from host.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
92cbfdaf682dca9cf60243f23c2e911181bfc7abKATOH Yasufumi if [ -n "$auth_key" -a -f "$auth_key" ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# Choose proxies for container
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# http_proxy will be used by debootstrap on the host.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# APT_PROXY will be used to set /etc/apt/apt.conf.d/70proxy in the container.
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi RES=`apt-config shell APT_PROXY Acquire::http::Proxy`
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi [ -z "$APT_PROXY" ] || export http_proxy=$APT_PROXY
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi # $3 => whether to use the multi-arch syntax or not
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi cat > $rootfs/etc/apt/apt.conf.d/70proxy << EOF
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH YasufumiAcquire::http::Proxy "$APT_PROXY" ;
db821c3a4168c9c1072a433340e6009892e26cf2KATOH Yasufumi MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
db821c3a4168c9c1072a433340e6009892e26cf2KATOH Yasufumi SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumideb [arch=$2] $MIRROR ${release} main restricted universe multiverse
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumideb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumideb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumideb $MIRROR ${release} main restricted universe multiverse
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumideb $MIRROR ${release}-updates main restricted universe multiverse
a1e4c206d5373b8ecd7906bff37f2601d65f022cKATOH Yasufumideb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Container upgrade failed. The container cache may be out of date,"
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "in which case flushing the case (see -F in the hep output) may help."
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi # Try to guess a list of langpacks to install
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if which dpkg >/dev/null 2>&1; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi dpkg -l | grep -E "^ii language-pack-[a-z]* " |
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi # check the mini ubuntu was not already downloaded
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $? -ne 0 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Failed to create '$cache/partial-$arch' directory"
bf3e09c00eab82850782ad6ec74e4403d84ae866KATOH Yasufumi choose_container_proxy $cache/partial-$arch/ $arch
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Downloading ubuntu $release minimal ..."
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi if [ $? -ne 0 ]; then
7a49a081dd1d4f92e3c82df344709e3206457e46KATOH Yasufumi echo "Failed to download the rootfs, aborting."
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi # Serge isn't sure whether we should avoid doing this when
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi write_sourceslist $cache/partial-$arch/ $arch
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $? -ne 0 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; }
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi rsync -Ha $cache/rootfs-$arch/ $rootfs/ || return 1
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $? -ne 0 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $flushcache -eq 1 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Checking cache download in $cache/rootfs-$arch ... "
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $? -ne 0 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Failed to download 'ubuntu $release base'"
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi echo "Copy $cache/rootfs-$arch to $rootfs ... "
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $? -ne 0 ]; then
8c3a756ed4cf22f9fdab5f95d067321e6ddcc425KATOH Yasufumi if [ -f $rootfs/etc/init/container-detect.conf ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi # if there is exactly one veth network entry, make sure it has an
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi if [ $nics -eq 1 ]; then
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi 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
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.mount = $path/fstab
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.pivotdir = lxc_putold
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.devttydir =$ttydir
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.pts = 1024
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.utsname = $name
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.arch = $arch
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumilxc.cap.drop = sys_module mac_admin mac_override sys_time
cab79123082bef9ba265c9c8b9176b8b8afedd64KATOH Yasufumi# When using LXC with apparmor, uncomment the next line to run unconfined:
if [ $? -ne 0 ]; then
rootfs=$1
release=$2
rootfs=$1
release=$2
if [ $trim_container -eq 1 ]; then
elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
cat /etc/resolv.conf > ${cresolvonf}
rm -f ${cresolvonf}
mv ${cresolvonf}.lxcbak ${cresolvonf}
mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
> ${rootfs}/etc/apt/sources.list
chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
rootfs=$1
user=$2
cat <<EOF
release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug,rootfs: -- "$@")
eval set -- "$options"
if [ -n "$bindhome" ]; then
echo "Error: no password entry found for $bindhome"
if [ -z "$path" ]; then
if [ -z "$rootfs" ]; then
echo "failed to install ubuntu $release"
echo "failed to configure ubuntu $release for a container"
if [ -n "$bindhome" ]; then
if [ -n "$bindhome" ]; then
echo "# Log in as user $bindhome"