On 11/29/2012 09:52 AM, Serge Hallyn wrote: > Quoting Stéphane Graber (stgra...@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 <stgra...@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.hal...@canonical.com> >> +# Copyright ? 2010 Wilhelm Meier >> +# Author: Wilhelm Meier <wilhelm.me...@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.hal...@canonical.com> >> -# Copyright ? 2010 Wilhelm Meier >> -# Author: Wilhelm Meier <wilhelm.me...@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@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/lxc-devel > -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: OpenPGP digital signature
------------------------------------------------------------------------------ Keep yourself connected to Go Parallel: VERIFY Test and improve your parallel project with help from experts and peers. http://goparallel.sourceforge.net
_______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel