patching the vref images was buggy
[sliceimage.git] / initscripts / lxc-sliceimage
index 07ff98a..3bf56ab 100755 (executable)
@@ -1,14 +1,24 @@
 #!/bin/bash
+#
 # chkconfig: 345 20 80
 # description: Create BTRFS subvolumes for LXC reference images.
 #
+# Thierry Parmentelat <thierry.parmentelat@inria.fr>
+# Copyright (C) 2012 INRIA
+#
 
 # not needed -- Source function library
 #. /etc/init.d/functions
 
+# a f>=18 root context won't have /bin nor /sbin in its path, which is where
+# chkconfig is located on f<=14 images
+export PATH=$PATH:/bin:/sbin
+
 # This is where sliceimage(s) store their reference images
 sliceimage_dir=/vservers/.vref
+sliceimage_stubs=/vservers/.vstub
 lxc_dir=/vservers/.lvref
+tmp_dir=/vservers/.ltmp
 
 # Check if we are in the build environment
 function check_node () {
@@ -30,10 +40,13 @@ function start () {
         # xxx what is that ?
        #btrfs subvolume create $lxc_dir/lxc-squeeze-x86_64
         # copy the slice image into the btrfs ?
-       rsync -av --delete $sliceimage_dir/$slicefamily/ $lxc_dir/$slicefamily/
+       rsync -a --delete $sliceimage_dir/$slicefamily/ $lxc_dir/$slicefamily/
        # tmp -- should very probably be done at build time
        patch_lvref $lxc_dir/$slicefamily
     done
+
+    # create ref images from stubs
+    unfold_system_slices
 }
 
 function status () {
@@ -46,13 +59,44 @@ function status () {
     ls $lxc_dir
 }
 
+# beware that patch_lvref_systemd will return early on non systemd-powered images
+function patch_lvref () {
+    rootfs=$1; shift
+    
+    # Allow a user who logins via ssh to sudo
+    chroot $rootfs sed -i 's/^Defaults\ *requiretty/\#&/' /etc/sudoers
+    # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd
+    # which cannot run inside a container.
+    chroot $rootfs sed -i 's/^.*loginuid.so.*$/\#&/' /etc/pam.d/login
+    # Enable eth0 on bootup
+    cat <<EOF > $rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
+DEVICE=eth0
+BOOTPROTO=dhcp
+ONBOOT=yes
+EOF
+    # Tweak sshd configuration
+    chroot $rootfs sed -i 's/^UsePAM\ *yes/\#&/' /etc/ssh/sshd_config
+    # commenting out the defaults in the file is not enough, need to explicitly set these to no
+    chroot $rootfs sed -i 's/^GSSAPIAuthentication.*$/GSSAPIAuthentication no/' /etc/ssh/sshd_config
+    chroot $rootfs sed -i 's/^PasswordAuthentication.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
+    # Allow root to login at virsh console
+    echo "pts/0" >> $rootfs/etc/securetty
+    # our image does not have NetworkManager, only network, and it is off by default
+    chroot $rootfs chkconfig network on
+
+    # this will run only if the rootfs seems to be systemd-based
+    patch_lvref_systemd $rootfs
+}
+
 # inspired from https://gist.github.com/1142202
 ETC=/etc/systemd/system
 LIB=/lib/systemd/system
-function patch_lvref () {
+function patch_lvref_systemd () {
+    rootfs=$1; shift
+
     # this applies to systemd only
     [ -d $rootfs/$LIB ] || return
-    rootfs=$1; shift
+
     # sliceimage comes with graphical.target as default
     chroot $rootfs ln -sf $LIB/multi-user.target $ETC/default.target
     # sysinit.target seems to stick on boot, so disable it. However, we need
@@ -76,26 +120,62 @@ function patch_lvref () {
     chroot $rootfs cp $LIB/getty\@.service $ETC/getty\@.service
     chroot $rootfs sed -i 's/^BindTo/\#&/' $ETC/getty\@.service
     chroot $rootfs ln -sf $ETC/getty\@.service $ETC/getty.target.wants/getty\@tty1.service
-    # Allow a user who logins via ssh to sudo
-    chroot $rootfs sed -i 's/^Defaults\ *requiretty/\#&/' /etc/sudoers
-    # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd
-    # which cannot run inside a container.
-    chroot $rootfs sed -i 's/^.*loginuid.so.*$/\#&/' /etc/pam.d/login
-    # Enable eth0 on bootup
-    cat <<EOF > $rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
-DEVICE=eth0
-BOOTPROTO=dhcp
-ONBOOT=yes
-EOF
-    # Tweak sshd configuration
-    chroot $rootfs sed -i 's/^UsePAM\ *yes/\#&/' /etc/ssh/sshd_config
-    # commenting out the defaults in the file is not enough, need to explicitly set these to no
-    chroot $rootfs sed -i 's/^GSSAPIAuthentication.*$/GSSAPIAuthentication no/' /etc/ssh/sshd_config
-    chroot $rootfs sed -i 's/^PasswordAuthentication.*$/PasswordAuthentication no/' /etc/ssh/sshd_config
-    # Allow root to login at virsh console
-    echo "pts/0" >> $rootfs/etc/securetty
-    # our image does not have NetworkManager, only network, and it is off by default
-    chroot $rootfs chkconfig network on
+
+}
+
+function unfold_system_slices () {
+    for clonedstamp in $sliceimage_stubs/*/*.cloned; do
+       unfold_system_slice_from_cloned $clonedstamp
+    done
+}
+
+function unfold_system_slice_from_cloned () {
+    clonedstamp=$1; shift
+    # e.g. NAME=planetflow
+    NAME=$(basename $clonedstamp .cloned)
+    DIR=$(dirname $clonedstamp)
+    # e.g. SLICEFAMILY=planetlab-f8-i386
+    SLICEFAMILY=$(cat $clonedstamp)
+    # deduce the actual name used in .vref by replacing the first part of slice-family 
+    # (pldistro) with the slice name
+    # e.g. VREFNAME=planetflow-f8-i386
+    VREFNAME=$(echo $SLICEFAMILY | sed -e "s,^[^-]*-,$NAME-,")
+
+    VREFPATH="$lxc_dir/$VREFNAME"
+
+    # do not redo existing vref's unless force is mentioned
+    [ -z "$FORCE" -a -d "$VREFPATH" ] && continue
+    [ -z "$FORCE" ] && message=Building
+    [ -n "$FORCE" ] && message=Force-building
+
+    # Copy base reference image
+    echo -n $"$message slice image for $NAME in $VREFNAME: "
+
+    # build the systemslice from the one it was originally cloned from
+    FAMILYREF="$lxc_dir/$SLICEFAMILY"
+    if [ ! -d "$FAMILYREF" ] ; then
+       echo system slice from $clonedstamp - could not find reference $FAMILYREF - skipped
+       return
+    fi
+    
+    # safe side
+    mkdir -p "$lxc_dir"
+    # cleanup reference image if already exists
+    [ -d "$VREFPATH" ] && btrfs subvolume delete "$VREFPATH"
+    # extra safe
+    [ -d "$VREFPATH" ] && rm -rf "$VREFPATH"
+
+    # clone subvolume
+    btrfs subvolume snapshot $FAMILYREF $VREFPATH
+    
+    # merge the stub with the reference to get the system slice
+    (cd "$DIR/$NAME"/ && find . | cpio -m -d -u -p "$VREFPATH"/) || \
+       { echo "Could not apply stub $DIR/$NAME - skipping $clonedstamp" ; btrfs subvolume delete "$VREFPATH" ; return ; }
+
+    # Clean RPM state
+    rm -f "$VREFPATH/var/lib/rpm/__db"*
+
+    echo Done
 }
 
 case "$1" in