[Lxc-users] [PATCH 6/9] ubuntu and ubuntu-cloud template updates:

Serge Hallyn serge at hallyn.com
Thu Apr 26 05:09:38 UTC 2012


From: Serge Hallyn <serge.hallyn at ubuntu.com>

ubuntu-cloud:
  . fix handling of non-precise cloud image format
  . add '--stream daily' option
  . fix handling of userdata (Ben Howard <ben.howard at canonical.com>)
  . extract the right filenames from tarball (Ben Howard <ben.howard at canonical.com>)
lxc-ubuntu:
  . use relative path as target for bind mount
    (An absolute path will be interpreted as absolute with respect to the
    parent's namespace.)
  . config layout tweak from Stéphane Graber <stgraber at ubuntu.com>

ubuntu and ubuntu-cloud: in precise, make /dev/shm a symbolic link to /run/shm

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Cc: Ben Howard <ben.howard at canonical.com>
Cc: Stéphane Graber <stgraber at ubuntu.com>
---
 templates/lxc-ubuntu-cloud.in |   86 +++++++++++++++++++++++++++++++++++------
 templates/lxc-ubuntu.in       |   36 ++++++++++++-----
 2 files changed, 101 insertions(+), 21 deletions(-)

diff --git a/templates/lxc-ubuntu-cloud.in b/templates/lxc-ubuntu-cloud.in
index 267dbab..493c10a 100644
--- a/templates/lxc-ubuntu-cloud.in
+++ b/templates/lxc-ubuntu-cloud.in
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# template script for generating ubuntu container for LXC based on daily cloud
+# template script for generating ubuntu container for LXC based on released cloud
 # images
 #
 # Copyright © 2012 Serge Hallyn <serge.hallyn at canonical.com>
@@ -31,6 +31,7 @@ copy_configuration()
     rootfs=$2
     name=$3
     arch=$4
+    release=$5
 
     if [ $arch = "i386" ]; then
         arch="i686"
@@ -41,7 +42,7 @@ copy_configuration()
     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/.$//')
+lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
 EOF
     fi
 
@@ -91,6 +92,16 @@ proc            $rootfs/proc         proc    nodev,noexec,nosuid 0 0
 sysfs           $rootfs/sys          sysfs defaults  0 0
 EOF
 
+    # rmdir /dev/shm in precise containers.
+    # 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 [ $release = "precise" ]; then
+        [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm
+        [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak
+        ln -s /run/shm $rootfs/dev/shm
+    fi
+
     return 0
 }
 
@@ -105,6 +116,7 @@ Generic Options
 [ -C | --cloud ]: Configure container for use with meta-data service, defaults to no
 [ -T | --tarball ]: Location of tarball
 [ -d | --debug ]: Run with 'set -x' to debug errors
+[ -s | --stream]: Use specified stream rather than 'released'
 
 Options, mutually exclusive of "-C" and "--cloud":
   [ -i | --hostid ]:    HostID for cloud-init, defaults to random string
@@ -116,7 +128,7 @@ EOF
     return 0
 }
 
-options=$(getopt -o a:hp:r:n:Fi:CLS:T:d -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug -- "$@")
+options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds: -l arch:,help,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata: -- "$@")
 if [ $? -ne 0 ]; then
     usage $(basename $0)
     exit 1
@@ -147,6 +159,10 @@ else
     elif [ "$arch" = "x86_64" ]; then
         arch="amd64"
     elif [ "$arch" = "armv7l" ]; then
+        # note: arm images don't exist before oneiric;  are called armhf in
+        # precise;  and are not supported by the query, so we don't actually
+        # support them yet (see check later on).  When Query2 is available,
+        # we'll use that to enable arm images.
         arch="armel"
     fi
 fi
@@ -156,6 +172,7 @@ hostarch=$arch
 cloud=0
 locales=1
 flushcache=0
+stream="released"
 while true
 do
     case "$1" in
@@ -172,12 +189,13 @@ do
     -L|--no_locales)   locales=0; shift 2;;
     -T|--tarball)      tarball=$2; shift 2;;
     -d|--debug)        debug=1; shift 1;;
+    -s|--stream)       stream=$2; shift 2;;
     --)                shift 1; break ;;
         *)              break ;;
     esac
 done
 
-if [ $debug -eq ]; then
+if [ $debug -eq 1 ]; then
     set -x
 fi
 
@@ -195,6 +213,16 @@ if [ $arch != "i386" -a $arch != "amd64" ]; then
     exit 1
 fi
 
+if [ "$stream" != "daily" -a "$stream" != "released" ]; then
+    echo "Only 'daily' and 'released' streams are supported"
+    exit 1
+fi
+
+if [ -n "$userdata" -a ! -f "$userdata" ]; then
+    echo "Userdata does not exist"
+    exit 1
+fi
+
 if [ -z "$path" ]; then
     echo "'path' parameter is required"
     exit 1
@@ -219,12 +247,47 @@ mkdir -p $cache
 if [ -n "$tarball" ]; then
 	url2="$tarball"
 else
-	url1=`ubuntu-cloudimg-query precise daily $arch --format "%{url}\n"`
+	url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`
 	url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/'`
 fi
 
 filename=`basename $url2`
 
+buildcleanup()
+{
+    cd $rootfs
+    umount -l $cache/$xdir || true
+    rm -rf $cache
+}
+
+# if the release doesn't have a *-rootfs.tar.gz, then create one from the
+# cloudimg.tar.gz by extracting the .img, mounting it loopback, and creating
+# a tarball from the mounted image.
+build_root_tgz()
+{
+    url=$1
+    filename=$2
+
+    xdir=`mktemp -d -p .`
+    tarname=`basename $url`
+    imgname="$release-*-cloudimg-$arch.img"
+    trap buildcleanup EXIT
+    if [ $flushcache -eq 1 -o ! -f $cache/$tarname ]; then
+        rm -f $tarname
+        echo "Downloading cloud image from $url"
+        wget $url || { echo "Couldn't find cloud image $url."; exit 1; }
+    fi
+    echo "Creating new cached cloud image rootfs"
+    tar --wildcards -zxf $tarname $imgname
+    mount -o loop $imgname $xdir
+    (cd $xdir; tar zcf ../$filename .)
+    umount $xdir
+    rm -f $tarname $imgname
+    rmdir $xdir
+    echo "New cloud image cache created"
+    trap EXIT
+}
+
 mkdir -p /var/lock/subsys/
 (
     flock -n -x 200
@@ -236,10 +299,10 @@ mkdir -p /var/lock/subsys/
     fi
 
     if [ ! -f $filename ]; then
-       wget $url2
+       wget $url2 || build_root_tgz $url1 $filename
     fi
 
-    echo "Extracting rootfs"
+    echo "Extracting container rootfs"
     mkdir -p $rootfs
     cd $rootfs
     tar -zxf $cache/$filename
@@ -275,8 +338,9 @@ EOF
 		echo "Inserted SSH public key from $auth_key into /home/ubuntu/.ssh/authorized_keys"
 	fi
 
-	if [ ! -f $userdata ]; then
-		cp $userdata $data_d/user-data
+	if [ -f "$userdata" ]; then
+		echo "Using custom user-data"
+		cp $userdata $seed_d/user-data
 	else
 
 		if [ -z "$MIRROR" ]; then
@@ -290,10 +354,10 @@ apt-mirror: $MIRROR
 manage_etc_hosts: localhost
 locale: $(/usr/bin/locale | awk -F= '/LANG=/ {print$NF}')
 EOF
-
 	fi
 
 	chroot $rootfs /usr/sbin/usermod -U ubuntu
+    	echo "ubuntu:ubuntu" | chroot $rootfs chpasswd
 	echo "Please login as user ubuntu with password ubuntu."
 
    else
@@ -305,7 +369,7 @@ EOF
 
 ) 200>/var/lock/subsys/lxc-ubucloud
 
-copy_configuration $path $rootfs $name $arch
+copy_configuration $path $rootfs $name $arch $release
 
 echo "Container $name created."
 exit 0
diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in
index aab941f..0c422ea 100644
--- a/templates/lxc-ubuntu.in
+++ b/templates/lxc-ubuntu.in
@@ -319,7 +319,7 @@ copy_configuration()
     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/.$//')
+lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
 EOF
     fi
 
@@ -517,6 +517,16 @@ post_process()
         chroot $rootfs apt-get update
         chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:amd64 iproute:amd64 isc-dhcp-client:amd64
     fi
+
+    # rmdir /dev/shm in precise containers.
+    # 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 [ $release = "precise" ]; then
+        [ -d "$rootfs/dev/shm" ] && rmdir $rootfs/dev/shm
+        [ -e "$rootfs/dev/shm" ] && mv $rootfs/dev/shm $rootfs/dev/shm.bak
+        ln -s /run/shm $rootfs/dev/shm
+    fi
 }
 
 do_bindhome()
@@ -543,13 +553,17 @@ do_bindhome()
     # bind-mount the user's path into the container's /home
     h=`getent passwd $user | cut -d: -f 6`
     mkdir -p $rootfs/$h
-    echo "$h $rootfs/$h none bind 0 0" >> $path/fstab
+    # 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
-    chroot $rootfs getent group $user || { \
-        grp=`getent group $user`
-        echo "$grp" >> $rootfs/etc/group
-    }
+    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()
@@ -630,10 +644,12 @@ if [ $debug -eq 1 ]; then
     set -x
 fi
 
-pwd=`getent passwd $bindhome`
-if [ $? -ne 0 ]; then
-    echo "Error: no password entry found for $bindhome"
-    exit 1
+if [ -n "$bindhome" ]; then
+    pwd=`getent passwd $bindhome`
+    if [ $? -ne 0 ]; then
+        echo "Error: no password entry found for $bindhome"
+        exit 1
+    fi
 fi
 
 
-- 
1.7.9.5





More information about the lxc-users mailing list