[lxc-devel] [PATCH 3/4] lxc-ubuntu: Rename from lxc-ubuntu.in
Stéphane Graber
stgraber at ubuntu.com
Thu Nov 29 15:11:39 UTC 2012
On 11/29/2012 09:52 AM, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
>> lxc-ubuntu no longer uses any build time variables, therefore it can
>> now be simply copied to the target without any autoconf magic.
>>
>> Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
>
> I'm trusting rather than verifying that the contents of
> lxc-ubuntu are identical to lxc-ubuntu.in? :)
Hehe, yeah, was just a simple "git mv", I wish git could somehow
indicate that in the diff...
> It could certainly be argued that it's preferable to handle
> all the templates the same way. What would you say is the
> advantage of doing this?
The main advantage for me is that when I see a template ending with .in
I do a full local test build and then try the template locally as it's
supposed to contain variables.
If it doesn't, I just run lxc-create -t <path> and I save a good 5
minutes :)
>> ---
>> configure.ac | 1 -
>> templates/lxc-ubuntu | 729 ++++++++++++++++++++++++++++++++++++++++++++++++
>> templates/lxc-ubuntu.in | 729 ------------------------------------------------
>> 3 files changed, 729 insertions(+), 730 deletions(-)
>> create mode 100644 templates/lxc-ubuntu
>> delete mode 100644 templates/lxc-ubuntu.in
>>
>> diff --git a/configure.ac b/configure.ac
>> index 5f0cc0b..b73e07b 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -244,7 +244,6 @@ AC_CONFIG_FILES([
>> templates/Makefile
>> templates/lxc-lenny
>> templates/lxc-debian
>> - templates/lxc-ubuntu
>> templates/lxc-ubuntu-cloud
>> templates/lxc-opensuse
>> templates/lxc-busybox
>> diff --git a/templates/lxc-ubuntu b/templates/lxc-ubuntu
>> new file mode 100644
>> index 0000000..ce1e065
>> --- /dev/null
>> +++ b/templates/lxc-ubuntu
>> @@ -0,0 +1,729 @@
>> +#!/bin/bash
>> +
>> +#
>> +# template script for generating ubuntu container for LXC
>> +#
>> +# This script consolidates and extends the existing lxc ubuntu scripts
>> +#
>> +
>> +# Copyright ? 2011 Serge Hallyn <serge.hallyn at canonical.com>
>> +# Copyright ? 2010 Wilhelm Meier
>> +# Author: Wilhelm Meier <wilhelm.meier at fh-kl.de>
>> +#
>> +# This program is free software; you can redistribute it and/or modify
>> +# it under the terms of the GNU General Public License version 2, as
>> +# published by the Free Software Foundation.
>> +
>> +# This program is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> +# GNU General Public License for more details.
>> +
>> +# You should have received a copy of the GNU General Public License along
>> +# with this program; if not, write to the Free Software Foundation, Inc.,
>> +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> +#
>> +
>> +set -e
>> +
>> +if [ -r /etc/default/lxc ]; then
>> + . /etc/default/lxc
>> +fi
>> +
>> +configure_ubuntu()
>> +{
>> + rootfs=$1
>> + hostname=$2
>> + release=$3
>> +
>> + # configure the network using the dhcp
>> + cat <<EOF > $rootfs/etc/network/interfaces
>> +# This file describes the network interfaces available on your system
>> +# and how to activate them. For more information, see interfaces(5).
>> +
>> +# The loopback network interface
>> +auto lo
>> +iface lo inet loopback
>> +
>> +auto eth0
>> +iface eth0 inet dhcp
>> +EOF
>> +
>> + # set the hostname
>> + cat <<EOF > $rootfs/etc/hostname
>> +$hostname
>> +EOF
>> + # set minimal hosts
>> + cat <<EOF > $rootfs/etc/hosts
>> +127.0.0.1 localhost
>> +127.0.1.1 $hostname
>> +
>> +# The following lines are desirable for IPv6 capable hosts
>> +::1 ip6-localhost ip6-loopback
>> +fe00::0 ip6-localnet
>> +ff00::0 ip6-mcastprefix
>> +ff02::1 ip6-allnodes
>> +ff02::2 ip6-allrouters
>> +EOF
>> +
>> + if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> + # suppress log level output for udev
>> + sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
>> +
>> + # remove jobs for consoles 5 and 6 since we only create 4 consoles in
>> + # this template
>> + rm -f $rootfs/etc/init/tty{5,6}.conf
>> + fi
>> +
>> + if [ -z "$bindhome" ]; then
>> + chroot $rootfs useradd --create-home -s /bin/bash ubuntu
>> + echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
>> + fi
>> +
>> + # make sure we have the current locale defined in the container
>> + if [ -z "$LANG" ]; then
>> + chroot $rootfs locale-gen en_US.UTF-8
>> + chroot $rootfs update-locale LANG=en_US.UTF-8
>> + else
>> + chroot $rootfs locale-gen $LANG
>> + chroot $rootfs update-locale LANG=$LANG
>> + fi
>> +
>> + return 0
>> +}
>> +
>> +# finish setting up the user in the container by injecting ssh key and
>> +# adding sudo group membership.
>> +# passed-in user is either 'ubuntu' or the user to bind in from host.
>> +finalize_user()
>> +{
>> + user=$1
>> +
>> + sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
>> +
>> + if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
>> + groups="sudo"
>> + else
>> + groups="sudo admin"
>> + fi
>> +
>> + for group in $groups; do
>> + chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
>> + chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
>> + done
>> +
>> + if [ -n "$auth_key" -a -f "$auth_key" ]; then
>> + u_path="/home/${user}/.ssh"
>> + root_u_path="$rootfs/$u_path"
>> + mkdir -p $root_u_path
>> + cp $auth_key "$root_u_path/authorized_keys"
>> + chroot $rootfs chown -R ${user}: "$u_path"
>> +
>> + echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
>> + fi
>> + return 0
>> +}
>> +
>> +write_sourceslist()
>> +{
>> + # $1 => path to the rootfs
>> + # $2 => architecture we want to add
>> + # $3 => whether to use the multi-arch syntax or not
>> +
>> + case $2 in
>> + amd64|i386)
>> + MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
>> + SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
>> + ;;
>> + *)
>> + MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> + SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> + ;;
>> + esac
>> + if [ -n "$3" ]; then
>> + cat >> "$1/etc/apt/sources.list" << EOF
>> +deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
>> +deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
>> +deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> +EOF
>> + else
>> + cat >> "$1/etc/apt/sources.list" << EOF
>> +deb $MIRROR ${release} main restricted universe multiverse
>> +deb $MIRROR ${release}-updates main restricted universe multiverse
>> +deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> +EOF
>> + fi
>> +}
>> +
>> +cleanup()
>> +{
>> + rm -rf $cache/partial-$arch
>> + rm -rf $cache/rootfs-$arch
>> +}
>> +
>> +suggest_flush()
>> +{
>> + echo "Container upgrade failed. The container cache may be out of date,"
>> + echo "in which case flushing the case (see -F in the hep output) may help."
>> +}
>> +
>> +download_ubuntu()
>> +{
>> + cache=$1
>> + arch=$2
>> + release=$3
>> +
>> + packages=vim,ssh
>> +
>> + # Try to guess a list of langpacks to install
>> + langpacks="language-pack-en"
>> +
>> + if which dpkg >/dev/null 2>&1; then
>> + langpacks=`(echo $LANGPACK_LIST &&
>> + dpkg -l | grep -E "^ii language-pack-[a-z]* " |
>> + cut -d ' ' -f3) | sort -u`
>> + fi
>> + packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
>> +
>> +
>> + echo "installing packages: $packages"
>> +
>> + trap cleanup EXIT SIGHUP SIGINT SIGTERM
>> + # check the mini ubuntu was not already downloaded
>> + mkdir -p "$cache/partial-$arch"
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to create '$cache/partial-$arch' directory"
>> + return 1
>> + fi
>> +
>> + # download a mini ubuntu into a cache
>> + echo "Downloading ubuntu $release minimal ..."
>> + if [ -n "$(which qemu-debootstrap)" ]; then
>> + qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> + else
>> + debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> + fi
>> +
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to download the rootfs, aborting."
>> + return 1
>> + fi
>> +
>> + # Serge isn't sure whether we should avoid doing this when
>> + # $release == `distro-info -d`
>> + echo "Installing updates"
>> + > $cache/partial-$arch/etc/apt/sources.list
>> + write_sourceslist $cache/partial-$arch/ $arch
>> +
>> + chroot "$1/partial-${arch}" apt-get update
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to update the apt cache"
>> + return 1
>> + fi
>> + cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
>> +#!/bin/sh
>> +exit 101
>> +EOF
>> + chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> +
>> + lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; }
>> + rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> +
>> + chroot "$1/partial-${arch}" apt-get clean
>> +
>> + mv "$1/partial-$arch" "$1/rootfs-$arch"
>> + trap EXIT
>> + trap SIGINT
>> + trap SIGTERM
>> + trap SIGHUP
>> + echo "Download complete"
>> + return 0
>> +}
>> +
>> +copy_ubuntu()
>> +{
>> + cache=$1
>> + arch=$2
>> + rootfs=$3
>> +
>> + # make a local copy of the miniubuntu
>> + echo "Copying rootfs to $rootfs ..."
>> + mkdir -p $rootfs
>> + rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
>> + return 0
>> +}
>> +
>> +install_ubuntu()
>> +{
>> + rootfs=$1
>> + release=$2
>> + flushcache=$3
>> + cache="/var/cache/lxc/$release"
>> + mkdir -p /var/lock/subsys/
>> +
>> + (
>> + flock -x 200
>> + if [ $? -ne 0 ]; then
>> + echo "Cache repository is busy."
>> + return 1
>> + fi
>> +
>> +
>> + if [ $flushcache -eq 1 ]; then
>> + echo "Flushing cache..."
>> + rm -rf "$cache/partial-$arch"
>> + rm -rf "$cache/rootfs-$arch"
>> + fi
>> +
>> + echo "Checking cache download in $cache/rootfs-$arch ... "
>> + if [ ! -e "$cache/rootfs-$arch" ]; then
>> + download_ubuntu $cache $arch $release
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to download 'ubuntu $release base'"
>> + return 1
>> + fi
>> + fi
>> +
>> + echo "Copy $cache/rootfs-$arch to $rootfs ... "
>> + copy_ubuntu $cache $arch $rootfs
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to copy rootfs"
>> + return 1
>> + fi
>> +
>> + return 0
>> +
>> + ) 200>/var/lock/subsys/lxc
>> +
>> + return $?
>> +}
>> +
>> +copy_configuration()
>> +{
>> + path=$1
>> + rootfs=$2
>> + name=$3
>> + arch=$4
>> + release=$5
>> +
>> + if [ $arch = "i386" ]; then
>> + arch="i686"
>> + fi
>> +
>> + ttydir=""
>> + if [ -f $rootfs/etc/init/container-detect.conf ]; then
>> + ttydir=" lxc"
>> + fi
>> +
>> + # if there is exactly one veth network entry, make sure it has an
>> + # associated hwaddr.
>> + nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
>> + if [ $nics -eq 1 ]; then
>> + grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
>> +lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
>> +EOF
>> + fi
>> +
>> + grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
>> + cat <<EOF >> $path/config
>> +lxc.utsname = $name
>> +
>> +lxc.devttydir =$ttydir
>> +lxc.tty = 4
>> +lxc.pts = 1024
>> +lxc.mount = $path/fstab
>> +lxc.arch = $arch
>> +lxc.cap.drop = sys_module mac_admin mac_override
>> +lxc.pivotdir = lxc_putold
>> +
>> +# When using LXC with apparmor, uncomment the next line to run unconfined:
>> +#lxc.aa_profile = unconfined
>> +
>> +lxc.cgroup.devices.deny = a
>> +# Allow any mknod (but not using the node)
>> +lxc.cgroup.devices.allow = c *:* m
>> +lxc.cgroup.devices.allow = b *:* m
>> +# /dev/null and zero
>> +lxc.cgroup.devices.allow = c 1:3 rwm
>> +lxc.cgroup.devices.allow = c 1:5 rwm
>> +# consoles
>> +lxc.cgroup.devices.allow = c 5:1 rwm
>> +lxc.cgroup.devices.allow = c 5:0 rwm
>> +#lxc.cgroup.devices.allow = c 4:0 rwm
>> +#lxc.cgroup.devices.allow = c 4:1 rwm
>> +# /dev/{,u}random
>> +lxc.cgroup.devices.allow = c 1:9 rwm
>> +lxc.cgroup.devices.allow = c 1:8 rwm
>> +lxc.cgroup.devices.allow = c 136:* rwm
>> +lxc.cgroup.devices.allow = c 5:2 rwm
>> +# rtc
>> +lxc.cgroup.devices.allow = c 254:0 rwm
>> +#fuse
>> +lxc.cgroup.devices.allow = c 10:229 rwm
>> +#tun
>> +lxc.cgroup.devices.allow = c 10:200 rwm
>> +#full
>> +lxc.cgroup.devices.allow = c 1:7 rwm
>> +#hpet
>> +lxc.cgroup.devices.allow = c 10:228 rwm
>> +#kvm
>> +lxc.cgroup.devices.allow = c 10:232 rwm
>> +EOF
>> +
>> + cat <<EOF > $path/fstab
>> +proc proc proc nodev,noexec,nosuid 0 0
>> +sysfs sys sysfs defaults 0 0
>> +EOF
>> +
>> + if [ $? -ne 0 ]; then
>> + echo "Failed to add configuration"
>> + return 1
>> + fi
>> +
>> + return 0
>> +}
>> +
>> +trim()
>> +{
>> + rootfs=$1
>> + release=$2
>> +
>> + # provide the lxc service
>> + cat <<EOF > $rootfs/etc/init/lxc.conf
>> +# fake some events needed for correct startup other services
>> +
>> +description "Container Upstart"
>> +
>> +start on startup
>> +
>> +script
>> + rm -rf /var/run/*.pid
>> + rm -rf /var/run/network/*
>> + /sbin/initctl emit stopped JOB=udevtrigger --no-wait
>> + /sbin/initctl emit started JOB=udev --no-wait
>> +end script
>> +EOF
>> +
>> + # fix buggus runlevel with sshd
>> + cat <<EOF > $rootfs/etc/init/ssh.conf
>> +# ssh - OpenBSD Secure Shell server
>> +#
>> +# The OpenSSH server provides secure shell access to the system.
>> +
>> +description "OpenSSH server"
>> +
>> +start on filesystem
>> +stop on runlevel [!2345]
>> +
>> +expect fork
>> +respawn
>> +respawn limit 10 5
>> +umask 022
>> +# replaces SSHD_OOM_ADJUST in /etc/default/ssh
>> +oom never
>> +
>> +pre-start script
>> + test -x /usr/sbin/sshd || { stop; exit 0; }
>> + test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
>> + test -c /dev/null || { stop; exit 0; }
>> +
>> + mkdir -p -m0755 /var/run/sshd
>> +end script
>> +
>> +# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
>> +# 'exec' line here instead
>> +exec /usr/sbin/sshd
>> +EOF
>> +
>> + cat <<EOF > $rootfs/etc/init/console.conf
>> +# console - getty
>> +#
>> +# This service maintains a console on tty1 from the point the system is
>> +# started until it is shut down again.
>> +
>> +start on stopped rc RUNLEVEL=[2345]
>> +stop on runlevel [!2345]
>> +
>> +respawn
>> +exec /sbin/getty -8 38400 /dev/console
>> +EOF
>> +
>> + cat <<EOF > $rootfs/lib/init/fstab
>> +# /lib/init/fstab: cleared out for bare-bones lxc
>> +EOF
>> +
>> + # remove pointless services in a container
>> + chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
>> +
>> + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
>> + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
>> + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
>> + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
>> + chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
>> +
>> + # if this isn't lucid, then we need to twiddle the network upstart bits :(
>> + if [ $release != "lucid" ]; then
>> + sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
>> + fi
>> +}
>> +
>> +post_process()
>> +{
>> + rootfs=$1
>> + release=$2
>> + trim_container=$3
>> +
>> + if [ $trim_container -eq 1 ]; then
>> + trim $rootfs $release
>> + elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> + # Make sure we have a working resolv.conf
>> + cresolvonf="${rootfs}/etc/resolv.conf"
>> + mv $cresolvonf ${cresolvonf}.lxcbak
>> + cat /etc/resolv.conf > ${cresolvonf}
>> +
>> + # for lucid, if not trimming, then add the ubuntu-virt
>> + # ppa and install lxcguest
>> + if [ $release = "lucid" ]; then
>> + chroot $rootfs apt-get update
>> + chroot $rootfs apt-get install --force-yes -y python-software-properties
>> + chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
>> + fi
>> +
>> + chroot $rootfs apt-get update
>> + chroot $rootfs apt-get install --force-yes -y lxcguest
>> +
>> + # Restore old resolv.conf
>> + rm -f ${cresolvonf}
>> + mv ${cresolvonf}.lxcbak ${cresolvonf}
>> + fi
>> +
>> + # If the container isn't running a native architecture, setup multiarch
>> + if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
>> + dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
>> + if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
>> + chroot $rootfs dpkg --add-architecture ${hostarch}
>> + else
>> + mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
>> + echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
>> + fi
>> +
>> + # Save existing value of MIRROR and SECURITY_MIRROR
>> + DEFAULT_MIRROR=$MIRROR
>> + DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
>> +
>> + # Write a new sources.list containing both native and multiarch entries
>> + > ${rootfs}/etc/apt/sources.list
>> + write_sourceslist $rootfs $arch "native"
>> +
>> + MIRROR=$DEFAULT_MIRROR
>> + SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
>> + write_sourceslist $rootfs $hostarch "multiarch"
>> +
>> + # Finally update the lists and install upstart using the host architecture
>> + chroot $rootfs apt-get update
>> + chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
>> + fi
>> +
>> + # rmdir /dev/shm for containers that have /run/shm
>> + # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
>> + # get bind mounted to the host's /run/shm. So try to rmdir
>> + # it, and in case that fails move it out of the way.
>> + if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
>> + mv $rootfs/dev/shm $rootfs/dev/shm.bak
>> + ln -s /run/shm $rootfs/dev/shm
>> + fi
>> +}
>> +
>> +do_bindhome()
>> +{
>> + rootfs=$1
>> + user=$2
>> +
>> + # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
>> + pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; }
>> + echo $pwd >> $rootfs/etc/passwd
>> +
>> + # make sure user's shell exists in the container
>> + shell=`echo $pwd | cut -d: -f 7`
>> + if [ ! -x $rootfs/$shell ]; then
>> + echo "shell $shell for user $user was not found in the container."
>> + pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1`
>> + echo "Installing $pkg"
>> + chroot $rootfs apt-get --force-yes -y install $pkg
>> + fi
>> +
>> + shad=`getent shadow $user`
>> + echo "$shad" >> $rootfs/etc/shadow
>> +
>> + # bind-mount the user's path into the container's /home
>> + h=`getent passwd $user | cut -d: -f 6`
>> + mkdir -p $rootfs/$h
>> +
>> + # use relative path in container
>> + h2=${h#/}
>> + while [ ${h2:0:1} = "/" ]; do
>> + h2=${h2#/}
>> + done
>> + echo "$h $h2 none bind 0 0" >> $path/fstab
>> +
>> + # Make sure the group exists in container
>> + grp=`echo $pwd | cut -d: -f 4` # group number for $user
>> + grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container
>> + chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group
>> +}
>> +
>> +usage()
>> +{
>> + cat <<EOF
>> +$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [--trim] [-d|--debug]
>> + [-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
>> +release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
>> +trim: make a minimal (faster, but not upgrade-safe) container
>> +bindhome: bind <user>'s home into the container
>> + The ubuntu user will not be created, and <user> will have
>> + sudo access.
>> +arch: the container architecture (e.g. amd64): defaults to host arch
>> +auth-key: SSH Public key file to inject into container
>> +EOF
>> + return 0
>> +}
>> +
>> +options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@")
>> +if [ $? -ne 0 ]; then
>> + usage $(basename $0)
>> + exit 1
>> +fi
>> +eval set -- "$options"
>> +
>> +release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
>> +if [ -f /etc/lsb-release ]; then
>> + . /etc/lsb-release
>> + if [ "$DISTRIB_ID" = "Ubuntu" ]; then
>> + release=$DISTRIB_CODENAME
>> + fi
>> +fi
>> +
>> +bindhome=
>> +arch=$(arch)
>> +
>> +# Code taken from debootstrap
>> +if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
>> + arch=`/usr/bin/dpkg --print-architecture`
>> +elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
>> + arch=`/usr/bin/udpkg --print-architecture`
>> +else
>> + arch=$(arch)
>> + if [ "$arch" = "i686" ]; then
>> + arch="i386"
>> + elif [ "$arch" = "x86_64" ]; then
>> + arch="amd64"
>> + elif [ "$arch" = "armv7l" ]; then
>> + arch="armel"
>> + fi
>> +fi
>> +
>> +debug=0
>> +trim_container=0
>> +hostarch=$arch
>> +flushcache=0
>> +while true
>> +do
>> + case "$1" in
>> + -h|--help) usage $0 && exit 0;;
>> + -p|--path) path=$2; shift 2;;
>> + -n|--name) name=$2; shift 2;;
>> + -F|--flush-cache) flushcache=1; shift 1;;
>> + -r|--release) release=$2; shift 2;;
>> + -b|--bindhome) bindhome=$2; shift 2;;
>> + -a|--arch) arch=$2; shift 2;;
>> + -x|--trim) trim_container=1; shift 1;;
>> + -S|--auth-key) auth_key=$2; shift 2;;
>> + -d|--debug) debug=1; shift 1;;
>> + --) shift 1; break ;;
>> + *) break ;;
>> + esac
>> +done
>> +
>> +if [ $debug -eq 1 ]; then
>> + set -x
>> +fi
>> +
>> +if [ -n "$bindhome" ]; then
>> + pwd=`getent passwd $bindhome`
>> + if [ $? -ne 0 ]; then
>> + echo "Error: no password entry found for $bindhome"
>> + exit 1
>> + fi
>> +fi
>> +
>> +
>> +if [ "$arch" == "i686" ]; then
>> + arch=i386
>> +fi
>> +
>> +if [ $hostarch = "i386" -a $arch = "amd64" ]; then
>> + echo "can't create amd64 container on i386"
>> + exit 1
>> +fi
>> +
>> +type debootstrap
>> +if [ $? -ne 0 ]; then
>> + echo "'debootstrap' command is missing"
>> + exit 1
>> +fi
>> +
>> +if [ -z "$path" ]; then
>> + echo "'path' parameter is required"
>> + exit 1
>> +fi
>> +
>> +if [ "$(id -u)" != "0" ]; then
>> + echo "This script should be run as 'root'"
>> + exit 1
>> +fi
>> +
>> +# detect rootfs
>> +config="$path/config"
>> +if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
>> + rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
>> +else
>> + rootfs=$path/rootfs
>> +fi
>> +
>> +install_ubuntu $rootfs $release $flushcache
>> +if [ $? -ne 0 ]; then
>> + echo "failed to install ubuntu $release"
>> + exit 1
>> +fi
>> +
>> +configure_ubuntu $rootfs $name $release
>> +if [ $? -ne 0 ]; then
>> + echo "failed to configure ubuntu $release for a container"
>> + exit 1
>> +fi
>> +
>> +copy_configuration $path $rootfs $name $arch $release
>> +if [ $? -ne 0 ]; then
>> + echo "failed write configuration file"
>> + exit 1
>> +fi
>> +
>> +post_process $rootfs $release $trim_container
>> +
>> +if [ -n "$bindhome" ]; then
>> + do_bindhome $rootfs $bindhome
>> + finalize_user $bindhome
>> +else
>> + finalize_user ubuntu
>> +fi
>> +
>> +echo ""
>> +echo "##"
>> +if [ -n "$bindhome" ]; then
>> + echo "# Log in as user $bindhome"
>> +else
>> + echo "# The default user is 'ubuntu' with password 'ubuntu'!"
>> + echo "# Use the 'sudo' command to run tasks as root in the container."
>> +fi
>> +echo "##"
>> +echo ""
>> diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in
>> deleted file mode 100644
>> index ce1e065..0000000
>> --- a/templates/lxc-ubuntu.in
>> +++ /dev/null
>> @@ -1,729 +0,0 @@
>> -#!/bin/bash
>> -
>> -#
>> -# template script for generating ubuntu container for LXC
>> -#
>> -# This script consolidates and extends the existing lxc ubuntu scripts
>> -#
>> -
>> -# Copyright ? 2011 Serge Hallyn <serge.hallyn at canonical.com>
>> -# Copyright ? 2010 Wilhelm Meier
>> -# Author: Wilhelm Meier <wilhelm.meier at fh-kl.de>
>> -#
>> -# This program is free software; you can redistribute it and/or modify
>> -# it under the terms of the GNU General Public License version 2, as
>> -# published by the Free Software Foundation.
>> -
>> -# This program is distributed in the hope that it will be useful,
>> -# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> -# GNU General Public License for more details.
>> -
>> -# You should have received a copy of the GNU General Public License along
>> -# with this program; if not, write to the Free Software Foundation, Inc.,
>> -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> -#
>> -
>> -set -e
>> -
>> -if [ -r /etc/default/lxc ]; then
>> - . /etc/default/lxc
>> -fi
>> -
>> -configure_ubuntu()
>> -{
>> - rootfs=$1
>> - hostname=$2
>> - release=$3
>> -
>> - # configure the network using the dhcp
>> - cat <<EOF > $rootfs/etc/network/interfaces
>> -# This file describes the network interfaces available on your system
>> -# and how to activate them. For more information, see interfaces(5).
>> -
>> -# The loopback network interface
>> -auto lo
>> -iface lo inet loopback
>> -
>> -auto eth0
>> -iface eth0 inet dhcp
>> -EOF
>> -
>> - # set the hostname
>> - cat <<EOF > $rootfs/etc/hostname
>> -$hostname
>> -EOF
>> - # set minimal hosts
>> - cat <<EOF > $rootfs/etc/hosts
>> -127.0.0.1 localhost
>> -127.0.1.1 $hostname
>> -
>> -# The following lines are desirable for IPv6 capable hosts
>> -::1 ip6-localhost ip6-loopback
>> -fe00::0 ip6-localnet
>> -ff00::0 ip6-mcastprefix
>> -ff02::1 ip6-allnodes
>> -ff02::2 ip6-allrouters
>> -EOF
>> -
>> - if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> - # suppress log level output for udev
>> - sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
>> -
>> - # remove jobs for consoles 5 and 6 since we only create 4 consoles in
>> - # this template
>> - rm -f $rootfs/etc/init/tty{5,6}.conf
>> - fi
>> -
>> - if [ -z "$bindhome" ]; then
>> - chroot $rootfs useradd --create-home -s /bin/bash ubuntu
>> - echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
>> - fi
>> -
>> - # make sure we have the current locale defined in the container
>> - if [ -z "$LANG" ]; then
>> - chroot $rootfs locale-gen en_US.UTF-8
>> - chroot $rootfs update-locale LANG=en_US.UTF-8
>> - else
>> - chroot $rootfs locale-gen $LANG
>> - chroot $rootfs update-locale LANG=$LANG
>> - fi
>> -
>> - return 0
>> -}
>> -
>> -# finish setting up the user in the container by injecting ssh key and
>> -# adding sudo group membership.
>> -# passed-in user is either 'ubuntu' or the user to bind in from host.
>> -finalize_user()
>> -{
>> - user=$1
>> -
>> - sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo)
>> -
>> - if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then
>> - groups="sudo"
>> - else
>> - groups="sudo admin"
>> - fi
>> -
>> - for group in $groups; do
>> - chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true
>> - chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true
>> - done
>> -
>> - if [ -n "$auth_key" -a -f "$auth_key" ]; then
>> - u_path="/home/${user}/.ssh"
>> - root_u_path="$rootfs/$u_path"
>> - mkdir -p $root_u_path
>> - cp $auth_key "$root_u_path/authorized_keys"
>> - chroot $rootfs chown -R ${user}: "$u_path"
>> -
>> - echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys"
>> - fi
>> - return 0
>> -}
>> -
>> -write_sourceslist()
>> -{
>> - # $1 => path to the rootfs
>> - # $2 => architecture we want to add
>> - # $3 => whether to use the multi-arch syntax or not
>> -
>> - case $2 in
>> - amd64|i386)
>> - MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu}
>> - SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu}
>> - ;;
>> - *)
>> - MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> - SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
>> - ;;
>> - esac
>> - if [ -n "$3" ]; then
>> - cat >> "$1/etc/apt/sources.list" << EOF
>> -deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
>> -deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
>> -deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> -EOF
>> - else
>> - cat >> "$1/etc/apt/sources.list" << EOF
>> -deb $MIRROR ${release} main restricted universe multiverse
>> -deb $MIRROR ${release}-updates main restricted universe multiverse
>> -deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
>> -EOF
>> - fi
>> -}
>> -
>> -cleanup()
>> -{
>> - rm -rf $cache/partial-$arch
>> - rm -rf $cache/rootfs-$arch
>> -}
>> -
>> -suggest_flush()
>> -{
>> - echo "Container upgrade failed. The container cache may be out of date,"
>> - echo "in which case flushing the case (see -F in the hep output) may help."
>> -}
>> -
>> -download_ubuntu()
>> -{
>> - cache=$1
>> - arch=$2
>> - release=$3
>> -
>> - packages=vim,ssh
>> -
>> - # Try to guess a list of langpacks to install
>> - langpacks="language-pack-en"
>> -
>> - if which dpkg >/dev/null 2>&1; then
>> - langpacks=`(echo $LANGPACK_LIST &&
>> - dpkg -l | grep -E "^ii language-pack-[a-z]* " |
>> - cut -d ' ' -f3) | sort -u`
>> - fi
>> - packages="$packages,$(echo $langpacks | sed 's/ /,/g')"
>> -
>> -
>> - echo "installing packages: $packages"
>> -
>> - trap cleanup EXIT SIGHUP SIGINT SIGTERM
>> - # check the mini ubuntu was not already downloaded
>> - mkdir -p "$cache/partial-$arch"
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to create '$cache/partial-$arch' directory"
>> - return 1
>> - fi
>> -
>> - # download a mini ubuntu into a cache
>> - echo "Downloading ubuntu $release minimal ..."
>> - if [ -n "$(which qemu-debootstrap)" ]; then
>> - qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> - else
>> - debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
>> - fi
>> -
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to download the rootfs, aborting."
>> - return 1
>> - fi
>> -
>> - # Serge isn't sure whether we should avoid doing this when
>> - # $release == `distro-info -d`
>> - echo "Installing updates"
>> - > $cache/partial-$arch/etc/apt/sources.list
>> - write_sourceslist $cache/partial-$arch/ $arch
>> -
>> - chroot "$1/partial-${arch}" apt-get update
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to update the apt cache"
>> - return 1
>> - fi
>> - cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
>> -#!/bin/sh
>> -exit 101
>> -EOF
>> - chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> -
>> - lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; }
>> - rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
>> -
>> - chroot "$1/partial-${arch}" apt-get clean
>> -
>> - mv "$1/partial-$arch" "$1/rootfs-$arch"
>> - trap EXIT
>> - trap SIGINT
>> - trap SIGTERM
>> - trap SIGHUP
>> - echo "Download complete"
>> - return 0
>> -}
>> -
>> -copy_ubuntu()
>> -{
>> - cache=$1
>> - arch=$2
>> - rootfs=$3
>> -
>> - # make a local copy of the miniubuntu
>> - echo "Copying rootfs to $rootfs ..."
>> - mkdir -p $rootfs
>> - rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
>> - return 0
>> -}
>> -
>> -install_ubuntu()
>> -{
>> - rootfs=$1
>> - release=$2
>> - flushcache=$3
>> - cache="/var/cache/lxc/$release"
>> - mkdir -p /var/lock/subsys/
>> -
>> - (
>> - flock -x 200
>> - if [ $? -ne 0 ]; then
>> - echo "Cache repository is busy."
>> - return 1
>> - fi
>> -
>> -
>> - if [ $flushcache -eq 1 ]; then
>> - echo "Flushing cache..."
>> - rm -rf "$cache/partial-$arch"
>> - rm -rf "$cache/rootfs-$arch"
>> - fi
>> -
>> - echo "Checking cache download in $cache/rootfs-$arch ... "
>> - if [ ! -e "$cache/rootfs-$arch" ]; then
>> - download_ubuntu $cache $arch $release
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to download 'ubuntu $release base'"
>> - return 1
>> - fi
>> - fi
>> -
>> - echo "Copy $cache/rootfs-$arch to $rootfs ... "
>> - copy_ubuntu $cache $arch $rootfs
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to copy rootfs"
>> - return 1
>> - fi
>> -
>> - return 0
>> -
>> - ) 200>/var/lock/subsys/lxc
>> -
>> - return $?
>> -}
>> -
>> -copy_configuration()
>> -{
>> - path=$1
>> - rootfs=$2
>> - name=$3
>> - arch=$4
>> - release=$5
>> -
>> - if [ $arch = "i386" ]; then
>> - arch="i686"
>> - fi
>> -
>> - ttydir=""
>> - if [ -f $rootfs/etc/init/container-detect.conf ]; then
>> - ttydir=" lxc"
>> - fi
>> -
>> - # if there is exactly one veth network entry, make sure it has an
>> - # associated hwaddr.
>> - nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
>> - if [ $nics -eq 1 ]; then
>> - grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
>> -lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
>> -EOF
>> - fi
>> -
>> - grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
>> - cat <<EOF >> $path/config
>> -lxc.utsname = $name
>> -
>> -lxc.devttydir =$ttydir
>> -lxc.tty = 4
>> -lxc.pts = 1024
>> -lxc.mount = $path/fstab
>> -lxc.arch = $arch
>> -lxc.cap.drop = sys_module mac_admin mac_override
>> -lxc.pivotdir = lxc_putold
>> -
>> -# When using LXC with apparmor, uncomment the next line to run unconfined:
>> -#lxc.aa_profile = unconfined
>> -
>> -lxc.cgroup.devices.deny = a
>> -# Allow any mknod (but not using the node)
>> -lxc.cgroup.devices.allow = c *:* m
>> -lxc.cgroup.devices.allow = b *:* m
>> -# /dev/null and zero
>> -lxc.cgroup.devices.allow = c 1:3 rwm
>> -lxc.cgroup.devices.allow = c 1:5 rwm
>> -# consoles
>> -lxc.cgroup.devices.allow = c 5:1 rwm
>> -lxc.cgroup.devices.allow = c 5:0 rwm
>> -#lxc.cgroup.devices.allow = c 4:0 rwm
>> -#lxc.cgroup.devices.allow = c 4:1 rwm
>> -# /dev/{,u}random
>> -lxc.cgroup.devices.allow = c 1:9 rwm
>> -lxc.cgroup.devices.allow = c 1:8 rwm
>> -lxc.cgroup.devices.allow = c 136:* rwm
>> -lxc.cgroup.devices.allow = c 5:2 rwm
>> -# rtc
>> -lxc.cgroup.devices.allow = c 254:0 rwm
>> -#fuse
>> -lxc.cgroup.devices.allow = c 10:229 rwm
>> -#tun
>> -lxc.cgroup.devices.allow = c 10:200 rwm
>> -#full
>> -lxc.cgroup.devices.allow = c 1:7 rwm
>> -#hpet
>> -lxc.cgroup.devices.allow = c 10:228 rwm
>> -#kvm
>> -lxc.cgroup.devices.allow = c 10:232 rwm
>> -EOF
>> -
>> - cat <<EOF > $path/fstab
>> -proc proc proc nodev,noexec,nosuid 0 0
>> -sysfs sys sysfs defaults 0 0
>> -EOF
>> -
>> - if [ $? -ne 0 ]; then
>> - echo "Failed to add configuration"
>> - return 1
>> - fi
>> -
>> - return 0
>> -}
>> -
>> -trim()
>> -{
>> - rootfs=$1
>> - release=$2
>> -
>> - # provide the lxc service
>> - cat <<EOF > $rootfs/etc/init/lxc.conf
>> -# fake some events needed for correct startup other services
>> -
>> -description "Container Upstart"
>> -
>> -start on startup
>> -
>> -script
>> - rm -rf /var/run/*.pid
>> - rm -rf /var/run/network/*
>> - /sbin/initctl emit stopped JOB=udevtrigger --no-wait
>> - /sbin/initctl emit started JOB=udev --no-wait
>> -end script
>> -EOF
>> -
>> - # fix buggus runlevel with sshd
>> - cat <<EOF > $rootfs/etc/init/ssh.conf
>> -# ssh - OpenBSD Secure Shell server
>> -#
>> -# The OpenSSH server provides secure shell access to the system.
>> -
>> -description "OpenSSH server"
>> -
>> -start on filesystem
>> -stop on runlevel [!2345]
>> -
>> -expect fork
>> -respawn
>> -respawn limit 10 5
>> -umask 022
>> -# replaces SSHD_OOM_ADJUST in /etc/default/ssh
>> -oom never
>> -
>> -pre-start script
>> - test -x /usr/sbin/sshd || { stop; exit 0; }
>> - test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
>> - test -c /dev/null || { stop; exit 0; }
>> -
>> - mkdir -p -m0755 /var/run/sshd
>> -end script
>> -
>> -# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
>> -# 'exec' line here instead
>> -exec /usr/sbin/sshd
>> -EOF
>> -
>> - cat <<EOF > $rootfs/etc/init/console.conf
>> -# console - getty
>> -#
>> -# This service maintains a console on tty1 from the point the system is
>> -# started until it is shut down again.
>> -
>> -start on stopped rc RUNLEVEL=[2345]
>> -stop on runlevel [!2345]
>> -
>> -respawn
>> -exec /sbin/getty -8 38400 /dev/console
>> -EOF
>> -
>> - cat <<EOF > $rootfs/lib/init/fstab
>> -# /lib/init/fstab: cleared out for bare-bones lxc
>> -EOF
>> -
>> - # remove pointless services in a container
>> - chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
>> -
>> - chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
>> - chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
>> - chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
>> - chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
>> - chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
>> -
>> - # if this isn't lucid, then we need to twiddle the network upstart bits :(
>> - if [ $release != "lucid" ]; then
>> - sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
>> - fi
>> -}
>> -
>> -post_process()
>> -{
>> - rootfs=$1
>> - release=$2
>> - trim_container=$3
>> -
>> - if [ $trim_container -eq 1 ]; then
>> - trim $rootfs $release
>> - elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
>> - # Make sure we have a working resolv.conf
>> - cresolvonf="${rootfs}/etc/resolv.conf"
>> - mv $cresolvonf ${cresolvonf}.lxcbak
>> - cat /etc/resolv.conf > ${cresolvonf}
>> -
>> - # for lucid, if not trimming, then add the ubuntu-virt
>> - # ppa and install lxcguest
>> - if [ $release = "lucid" ]; then
>> - chroot $rootfs apt-get update
>> - chroot $rootfs apt-get install --force-yes -y python-software-properties
>> - chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
>> - fi
>> -
>> - chroot $rootfs apt-get update
>> - chroot $rootfs apt-get install --force-yes -y lxcguest
>> -
>> - # Restore old resolv.conf
>> - rm -f ${cresolvonf}
>> - mv ${cresolvonf}.lxcbak ${cresolvonf}
>> - fi
>> -
>> - # If the container isn't running a native architecture, setup multiarch
>> - if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
>> - dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
>> - if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
>> - chroot $rootfs dpkg --add-architecture ${hostarch}
>> - else
>> - mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
>> - echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
>> - fi
>> -
>> - # Save existing value of MIRROR and SECURITY_MIRROR
>> - DEFAULT_MIRROR=$MIRROR
>> - DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
>> -
>> - # Write a new sources.list containing both native and multiarch entries
>> - > ${rootfs}/etc/apt/sources.list
>> - write_sourceslist $rootfs $arch "native"
>> -
>> - MIRROR=$DEFAULT_MIRROR
>> - SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
>> - write_sourceslist $rootfs $hostarch "multiarch"
>> -
>> - # Finally update the lists and install upstart using the host architecture
>> - chroot $rootfs apt-get update
>> - chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
>> - fi
>> -
>> - # rmdir /dev/shm for containers that have /run/shm
>> - # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
>> - # get bind mounted to the host's /run/shm. So try to rmdir
>> - # it, and in case that fails move it out of the way.
>> - if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
>> - mv $rootfs/dev/shm $rootfs/dev/shm.bak
>> - ln -s /run/shm $rootfs/dev/shm
>> - fi
>> -}
>> -
>> -do_bindhome()
>> -{
>> - rootfs=$1
>> - user=$2
>> -
>> - # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
>> - pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; }
>> - echo $pwd >> $rootfs/etc/passwd
>> -
>> - # make sure user's shell exists in the container
>> - shell=`echo $pwd | cut -d: -f 7`
>> - if [ ! -x $rootfs/$shell ]; then
>> - echo "shell $shell for user $user was not found in the container."
>> - pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1`
>> - echo "Installing $pkg"
>> - chroot $rootfs apt-get --force-yes -y install $pkg
>> - fi
>> -
>> - shad=`getent shadow $user`
>> - echo "$shad" >> $rootfs/etc/shadow
>> -
>> - # bind-mount the user's path into the container's /home
>> - h=`getent passwd $user | cut -d: -f 6`
>> - mkdir -p $rootfs/$h
>> -
>> - # use relative path in container
>> - h2=${h#/}
>> - while [ ${h2:0:1} = "/" ]; do
>> - h2=${h2#/}
>> - done
>> - echo "$h $h2 none bind 0 0" >> $path/fstab
>> -
>> - # Make sure the group exists in container
>> - grp=`echo $pwd | cut -d: -f 4` # group number for $user
>> - grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container
>> - chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group
>> -}
>> -
>> -usage()
>> -{
>> - cat <<EOF
>> -$1 -h|--help [-a|--arch] [-b|--bindhome <user>] [--trim] [-d|--debug]
>> - [-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
>> -release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
>> -trim: make a minimal (faster, but not upgrade-safe) container
>> -bindhome: bind <user>'s home into the container
>> - The ubuntu user will not be created, and <user> will have
>> - sudo access.
>> -arch: the container architecture (e.g. amd64): defaults to host arch
>> -auth-key: SSH Public key file to inject into container
>> -EOF
>> - return 0
>> -}
>> -
>> -options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,bindhome:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@")
>> -if [ $? -ne 0 ]; then
>> - usage $(basename $0)
>> - exit 1
>> -fi
>> -eval set -- "$options"
>> -
>> -release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
>> -if [ -f /etc/lsb-release ]; then
>> - . /etc/lsb-release
>> - if [ "$DISTRIB_ID" = "Ubuntu" ]; then
>> - release=$DISTRIB_CODENAME
>> - fi
>> -fi
>> -
>> -bindhome=
>> -arch=$(arch)
>> -
>> -# Code taken from debootstrap
>> -if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
>> - arch=`/usr/bin/dpkg --print-architecture`
>> -elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
>> - arch=`/usr/bin/udpkg --print-architecture`
>> -else
>> - arch=$(arch)
>> - if [ "$arch" = "i686" ]; then
>> - arch="i386"
>> - elif [ "$arch" = "x86_64" ]; then
>> - arch="amd64"
>> - elif [ "$arch" = "armv7l" ]; then
>> - arch="armel"
>> - fi
>> -fi
>> -
>> -debug=0
>> -trim_container=0
>> -hostarch=$arch
>> -flushcache=0
>> -while true
>> -do
>> - case "$1" in
>> - -h|--help) usage $0 && exit 0;;
>> - -p|--path) path=$2; shift 2;;
>> - -n|--name) name=$2; shift 2;;
>> - -F|--flush-cache) flushcache=1; shift 1;;
>> - -r|--release) release=$2; shift 2;;
>> - -b|--bindhome) bindhome=$2; shift 2;;
>> - -a|--arch) arch=$2; shift 2;;
>> - -x|--trim) trim_container=1; shift 1;;
>> - -S|--auth-key) auth_key=$2; shift 2;;
>> - -d|--debug) debug=1; shift 1;;
>> - --) shift 1; break ;;
>> - *) break ;;
>> - esac
>> -done
>> -
>> -if [ $debug -eq 1 ]; then
>> - set -x
>> -fi
>> -
>> -if [ -n "$bindhome" ]; then
>> - pwd=`getent passwd $bindhome`
>> - if [ $? -ne 0 ]; then
>> - echo "Error: no password entry found for $bindhome"
>> - exit 1
>> - fi
>> -fi
>> -
>> -
>> -if [ "$arch" == "i686" ]; then
>> - arch=i386
>> -fi
>> -
>> -if [ $hostarch = "i386" -a $arch = "amd64" ]; then
>> - echo "can't create amd64 container on i386"
>> - exit 1
>> -fi
>> -
>> -type debootstrap
>> -if [ $? -ne 0 ]; then
>> - echo "'debootstrap' command is missing"
>> - exit 1
>> -fi
>> -
>> -if [ -z "$path" ]; then
>> - echo "'path' parameter is required"
>> - exit 1
>> -fi
>> -
>> -if [ "$(id -u)" != "0" ]; then
>> - echo "This script should be run as 'root'"
>> - exit 1
>> -fi
>> -
>> -# detect rootfs
>> -config="$path/config"
>> -if grep -q '^lxc.rootfs' $config 2>/dev/null ; then
>> - rootfs=`grep 'lxc.rootfs =' $config | awk -F= '{ print $2 }'`
>> -else
>> - rootfs=$path/rootfs
>> -fi
>> -
>> -install_ubuntu $rootfs $release $flushcache
>> -if [ $? -ne 0 ]; then
>> - echo "failed to install ubuntu $release"
>> - exit 1
>> -fi
>> -
>> -configure_ubuntu $rootfs $name $release
>> -if [ $? -ne 0 ]; then
>> - echo "failed to configure ubuntu $release for a container"
>> - exit 1
>> -fi
>> -
>> -copy_configuration $path $rootfs $name $arch $release
>> -if [ $? -ne 0 ]; then
>> - echo "failed write configuration file"
>> - exit 1
>> -fi
>> -
>> -post_process $rootfs $release $trim_container
>> -
>> -if [ -n "$bindhome" ]; then
>> - do_bindhome $rootfs $bindhome
>> - finalize_user $bindhome
>> -else
>> - finalize_user ubuntu
>> -fi
>> -
>> -echo ""
>> -echo "##"
>> -if [ -n "$bindhome" ]; then
>> - echo "# Log in as user $bindhome"
>> -else
>> - echo "# The default user is 'ubuntu' with password 'ubuntu'!"
>> - echo "# Use the 'sudo' command to run tasks as root in the container."
>> -fi
>> -echo "##"
>> -echo ""
>> --
>> 1.8.0
>>
>>
>
>> ------------------------------------------------------------------------------
>> Keep yourself connected to Go Parallel:
>> INSIGHTS What's next for parallel hardware, programming and related areas?
>> Interviews and blogs by thought leaders keep you ahead of the curve.
>> http://goparallel.sourceforge.net
>
>> _______________________________________________
>> Lxc-devel mailing list
>> Lxc-devel at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/lxc-devel
>
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121129/ed651efe/attachment.pgp>
More information about the lxc-devel
mailing list