X-Git-Url: http://git.onelab.eu/?p=sliceimage.git;a=blobdiff_plain;f=bin%2Flxc-sliceimage;fp=bin%2Flxc-sliceimage;h=51ff6597b08f30e1d67d1339a4ad956fe7f3f5c4;hp=0000000000000000000000000000000000000000;hb=2a061d4cdf91279d1a72c1c07cad94da519b744e;hpb=e7ad727221575d4adb262862b0823e985e679fb9 diff --git a/bin/lxc-sliceimage b/bin/lxc-sliceimage new file mode 100755 index 0000000..51ff659 --- /dev/null +++ b/bin/lxc-sliceimage @@ -0,0 +1,233 @@ +#!/bin/bash +# +# chkconfig: 345 20 80 +# description: Create BTRFS subvolumes for LXC reference images. +# +# Thierry Parmentelat +# 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) rpms 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 () { + mount | grep -q 'planetlab-vservers' || exit 0 + [ -d $sliceimage_dir ] || { echo "No sliceimage installed" ; exit 1; } +} + +function start () { + + echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + echo "lxc-sliceimage: starting on $(date)" + + check_node + + mkdir -p $lxc_dir + + slicefamilies=$(cd $sliceimage_dir ; ls ) + + for slicefamily in $slicefamilies; do + echo ==================== $slicefamily + # initialize if needed + [ -d $lxc_dir/$slicefamily ] || { + echo "creating btrfs subvolume" ; + btrfs subvolume create $lxc_dir/$slicefamily ; + } + # xxx what is that ? + #btrfs subvolume create $lxc_dir/lxc-squeeze-x86_64 + # copy the slice image into the btrfs ? +# echo "============================== mirroring start $(date)" + echo "$sliceimage_dir/$slicefamily/ onto btrfs subvolume $lxc_dir/$slicefamily/" + # mention --delete for rpm updates + # we want to keep only our own additions, that will be re-created in the remaining + # of this script anyway + rsync -a --delete $sliceimage_dir/$slicefamily/ $lxc_dir/$slicefamily/ +# echo "============================== mirroring done $(date)" + # adapting slice images to the node virtualization mode can unfortunately + # not be done at build-time since we do not know that yet + patch_lvref $lxc_dir/$slicefamily + done + + # create ref images from stubs + unfold_system_slices + + echo "lxc-sliceimage: done on $(date)" + echo "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" +} + +function status () { + echo -n "Checking node .. " + check_node + echo OK + echo "From installed sliceimage variants" + ls $sliceimage_dir + echo "Exported to lxc" + ls $lxc_dir +} + +# prefer to use e.g. +# sed -i $rootfs/etc/sudoers +# rather than +# chroot $rootfs sed -i /etc/sudoers +# because the latter has sed issue weird messages like +# sed: warning: failed to get security context of ... +function patch_lvref () { + rootfs=$1; shift + + echo "patch_lvref : handling $rootfs" + + # Allow a user who logins via ssh to sudo + sed -i 's/^Defaults\ *requiretty/\#&/' $rootfs/etc/sudoers + # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd + # which cannot run inside a container. + sed -i 's/^.*loginuid.so.*$/\#&/' $rootfs/etc/pam.d/login + # Enable eth0 on bootup + cat < $rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 +DEVICE=eth0 +BOOTPROTO=dhcp +ONBOOT=yes +EOF + # Tweak sshd configuration - not all slice images have sshd preinstalled + if [ -f $rootfs/etc/ssh/sshd_config ] ; then + sed -e 's/^UsePAM\ *yes/\#&/' \ + -e 's/^GSSAPIAuthentication.*$/GSSAPIAuthentication no/' \ + -e 's/^PasswordAuthentication.*$/PasswordAuthentication no/' \ + -i $rootfs/etc/ssh/sshd_config + fi + # 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 +} + +# beware that patch_lvref_systemd will return early on non systemd-powered images +# inspired from https://gist.github.com/1142202 +ETC=/etc/systemd/system +LIB=/lib/systemd/system + +function patch_lvref_systemd () { + rootfs=$1; shift + + absetc=$rootfs/$ETC + abslib=$rootfs/$LIB + + # this applies to systemd only + [ -d $abslib ] || return + + # stay away from trouble, avoid chroot'ing for straightforward stuff + echo "patch_lvref_systemd: handling $rootfs" + # sliceimage comes with graphical.target as default + ln -sf $LIB/multi-user.target $absetc/default.target + # sysinit.target seems to stick on boot, so disable it. However, we need + # systemd-tmpfiles-setup.service that was started by the dependency of + # sysinit.target to boot up correctly, so start it instead. + cp $abslib/basic.target $absetc/basic.target + sed -e 's/sysinit.target/systemd-tmpfiles-setup.service/' -i $absetc/basic.target + # Stop starting sysinit.target. Symlinking one to /dev/null is a standard way + # to disable a target (or a service and others). + ln -sf /dev/null $absetc/sysinit.target + # is also a cause of stuck on boot + ln -sf /dev/null $absetc/udev-settle.service + # It prevents systemd-tmpfiles-setup.service from starting + ln -sf /dev/null $absetc/fedora-readonly.service + # Libvirt lxc provides only tty1 + rm -f $absetc/getty.target.wants/getty\@tty{2,3,4,5,6}.service + # It launches sulogin on console(tty1) but it interferes getty@tty1 + ln -sf /dev/null $absetc/console-shell.service + # Workarounds for libvirt 0.9.4. Without this, getty@tty1 doen't launch + # because a trigger event on tty1 doesn't happen. + cp $abslib/getty\@.service $absetc/getty\@.service + sed -e 's/^BindTo/\#&/' -i $absetc/getty\@.service + ln -sf $ETC/getty\@.service $absetc/getty.target.wants/getty\@tty1.service + +} + +function unfold_system_slices () { + for clonedstamp in $sliceimage_stubs/*/*.cloned; do + unfold_system_slice_from_cloned $clonedstamp + done +} + +# untested - how does this behave when updating the slice reference image ? +# OTOH system slices probably already run at update-time +# so it's kind of too late anyways +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" ] && { + echo "unfold_system_slice_from_cloned : $VREFPATH looks fine" ; + return ; + } + [ -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 +} + +# run with the --tty option to see results, otherwise get that logged +case "$1" in + --tty) shift;; + *) exec >> /var/log/lxc-sliceimage.log 2>&1 ;; +esac + +case "$1" in + start|restart|reload) start ; exit 0 ;; + status) status ; exit 0 ;; + stop) exit 0 ;; + *) echo $"Usage: $0 [--tty] {start|stop|status}" + exit 1 + ;; +esac