X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lbuild-initvm.sh;h=307beb65f87a0bb314e570ee435f0fe979f32784;hb=9f78868e322225c40e8ec008d91510aa5bdb03ea;hp=089289d099d343fbe443ca38d11368e4886f2b0a;hpb=10f1120c5a2d59cc3d89b00a7a390c96d4246472;p=build.git diff --git a/lbuild-initvm.sh b/lbuild-initvm.sh index 089289d0..307beb65 100755 --- a/lbuild-initvm.sh +++ b/lbuild-initvm.sh @@ -21,10 +21,10 @@ export PATH=$PATH:/bin:/sbin # XXX fixme : when creating a 32bits VM we need to call linux32 as appropriate...s -DEFAULT_FCDISTRO=f20 +DEFAULT_FCDISTRO=f21 DEFAULT_PLDISTRO=lxc DEFAULT_PERSONALITY=linux64 -DEFAULT_MEMORY=512 +DEFAULT_MEMORY=1024 ########## # constant @@ -73,7 +73,7 @@ function package_method () { fcdistro=$1; shift case $fcdistro in f[0-9]*|centos[0-9]*|sl[0-9]*) echo yum ;; - squeeze|wheezy|jessie|oneiric|precise|quantal|raring|saucy|trusty) echo debootstrap ;; + squeeze|wheezy|jessie|oneiric|precise|quantal|raring|saucy|trusty|utopic) echo debootstrap ;; *) echo Unknown distro $fcdistro ;; esac } @@ -165,10 +165,13 @@ function fedora_download() { MIRROR_URL=$FEDORA_MIRROR_BASE/releases/$release/Everything/$arch/os RELEASE_URL1="$MIRROR_URL/Packages/fedora-release-$release-1.noarch.rpm" # with fedora18 the rpms are scattered by first name - RELEASE_URL2="$MIRROR_URL/Packages/f/fedora-release-$release-1.noarch.rpm" + # first try the second version of fedora-release first + RELEASE_URL2="$MIRROR_URL/Packages/f/fedora-release-$release-2.noarch.rpm" + RELEASE_URL3="$MIRROR_URL/Packages/f/fedora-release-$release-1.noarch.rpm" + RELEASE_TARGET=$INSTALL_ROOT/fedora-release-$release.noarch.rpm found="" - for attempt in $RELEASE_URL1 $RELEASE_URL2; do + for attempt in $RELEASE_URL1 $RELEASE_URL2 $RELEASE_URL3; do if curl -f $attempt -o $RELEASE_TARGET ; then echo "Retrieved $attempt" found=true @@ -262,7 +265,7 @@ EOF fi guest_ifcfg=${lxc_root}/etc/sysconfig/network-scripts/ifcfg-$VIF_GUEST - ( [ -n "$BUILD_MODE" ] && write_guest_ifcfg_build || write_guest_ifcfg_test ) > $guest_ifcfg + ( [ -n "$NAT_MODE" ] && write_guest_ifcfg_natip || write_guest_ifcfg_publicip ) > $guest_ifcfg [ -z "$IMAGE" ] && fedora_configure_yum $lxc $fcdistro $pldistro @@ -277,8 +280,8 @@ function fedora_configure_init() { # don't mount devpts, for pete's sake sed -i 's/^.*dev.pts.*$/#\0/' ${lxc_root}/etc/rc.sysinit sed -i 's/^.*dev.pts.*$/#\0/' ${lxc_root}/etc/rc.d/rc.sysinit - chroot ${lxc_root} chkconfig udev-post off - chroot ${lxc_root} chkconfig network on + chroot ${lxc_root} $personality chkconfig udev-post off + chroot ${lxc_root} $personality chkconfig network on } # this code of course is for guests that do run on systemd @@ -291,17 +294,13 @@ function fedora_configure_systemd() { ln -sf /lib/systemd/system/multi-user.target ${lxc_root}/etc/systemd/system/default.target touch ${lxc_root}/etc/fstab ln -sf /dev/null ${lxc_root}/etc/systemd/system/udev.service -# Thierry - Feb 2013 -# this was intended for f16 initially, in order to enable getty that otherwise would not start -# having a getty running is helpful only if ssh won't start though, and we see a correlation between -# VM's that refuse to lxc-stop and VM's that run crazy getty's +# Thierry - Feb 2013 relying on getty is looking for trouble # so, turning getty off for now instead -# #dependency on a device unit fails it specially that we disabled udev # sed -i 's/After=dev-%i.device/After=/' ${lxc_root}/lib/systemd/system/getty\@.service ln -sf /dev/null ${lxc_root}/etc/systemd/system/"getty@.service" rm -f ${lxc_root}/etc/systemd/system/getty.target.wants/*service || : # can't seem to handle this one with systemctl - chroot ${lxc_root} chkconfig network on + chroot ${lxc_root} $personality chkconfig network on } # overwrite container yum config @@ -315,7 +314,7 @@ function fedora_configure_yum () { pldistro=$1; shift # rpm --rebuilddb - chroot $lxc_root rpm --rebuilddb + chroot ${lxc_root} $personality rpm --rebuilddb echo "Initializing yum.repos.d in $lxc" rm -f $lxc_root/etc/yum.repos.d/* @@ -338,7 +337,7 @@ gpgcheck=1 gpgkey=$FEDORA_MIRROR_KEYS/RPM-GPG-KEY-fedora-$release-primary EOF - # for using vtest-init-lxc.sh as a general-purpose lxc creation wrapper + # for using this script as a general-purpose lxc creation wrapper # just mention 'none' as the repo url if [ -n "$REPO_URL" ] ; then if [ ! -d $lxc_root/etc/yum.repos.d ] ; then @@ -368,7 +367,7 @@ function debian_mirror () { case $fcdistro in squeeze|wheezy|jessie) echo http://ftp2.fr.debian.org/debian/ ;; - oneiric|precise|quantal|raring|saucy|trusty) + oneiric|precise|quantal|raring|saucy|trusty|utopic) echo http://mir1.ovh.net/ubuntu/ubuntu/ ;; *) echo unknown distro $fcdistro; exit 1;; esac @@ -384,10 +383,10 @@ function debian_install () { debootstrap --arch $arch $fcdistro $lxc_root $mirror # just like with fedora we ensure a few packages get installed as well # not started yet - #virsh -c lxc:/// lxc-enter-namespace $lxc /bin/bash -c "apt-get update" - #virsh -c lxc:/// lxc-enter-namespace $lxc /bin/bash -c "apt-get -y install $DEBIAN_PREINSTALLED" - chroot $lxc_root apt-get update - chroot $lxc_root apt-get -y install $DEBIAN_PREINSTALLED + #virsh -c lxc:/// lxc-enter-namespace $lxc /usr/bin/$personality /bin/bash -c "apt-get update" + #virsh -c lxc:/// lxc-enter-namespace $lxc /usr/bin/$personality /bin/bash -c "apt-get -y install $DEBIAN_PREINSTALLED" + chroot ${lxc_root} $personality apt-get update + chroot ${lxc_root} $personality apt-get -y install $DEBIAN_PREINSTALLED # configure hostname cat < ${lxc_root}/etc/hostname $GUEST_HOSTNAME @@ -397,17 +396,17 @@ EOF function debian_configure () { guest_interfaces=${lxc_root}/etc/network/interfaces - ( [ -n "$BUILD_MODE" ] && write_guest_interfaces_build || write_guest_interfaces_test ) > $guest_interfaces + ( [ -n "$NAT_MODE" ] && write_guest_interfaces_natip || write_guest_interfaces_publicip ) > $guest_interfaces } -function write_guest_interfaces_build () { +function write_guest_interfaces_natip () { cat < $lxc_root/etc/hosts # grant ssh access from host to guest @@ -466,7 +467,7 @@ function setup_lxc() { # don't keep the input xml, this can be retrieved at all times with virsh dumpxml config_xml=/tmp/$lxc.xml - ( [ -n "$BUILD_MODE" ] && write_lxc_xml_build $lxc || write_lxc_xml_test $lxc ) > $config_xml + ( [ -n "$NAT_MODE" ] && write_lxc_xml_natip $lxc || write_lxc_xml_publicip $lxc ) > $config_xml # define lxc container for libvirt virsh -c lxc:/// define $config_xml @@ -474,7 +475,16 @@ function setup_lxc() { return 0 } -function write_lxc_xml_test () { +# this part does not belong in a domain any more +# but goes in a network object of its own existence +# +# host-bridge +# +# +# +# + +function write_lxc_xml_publicip () { lxc=$1; shift cat < @@ -504,16 +514,11 @@ function write_lxc_xml_test () { - - host-bridge - - - EOF } -function write_lxc_xml_build () { +function write_lxc_xml_natip () { lxc=$1; shift cat < @@ -547,7 +552,7 @@ EOF } # this one is dhcp-based -function write_guest_ifcfg_build () { +function write_guest_ifcfg_natip () { cat < $lxc_root/init-lxc.rpms + chroot ${lxc_root} $personality rpm -aq > $lxc_root/init-lxc.rpms ;; debootstrap) # for ubuntu @@ -622,8 +627,8 @@ function devel_or_vtest_tools () { fi for package in $packages ; do # container not started yet - #virsh -c lxc:/// lxc-enter-namespace $lxc /bin/bash -c "apt-get install -y $package" || : - chroot $lxc_root apt-get install -y $package || : + #virsh -c lxc:/// lxc-enter-namespace $lxc /usr/bin/$personality /bin/bash -c "apt-get install -y $package" || : + chroot ${lxc_root} $personality apt-get install -y $package || : done ### xxx todo install groups with apt.. ;; @@ -640,26 +645,21 @@ function post_install () { personality=$1; shift # setup localtime from the host cp /etc/localtime $lxc_root/etc/localtime - if [ -n "$BUILD_MODE" ] ; then - post_install_build $lxc $personality - if [ -n "$START_VM" ] ; then - virsh -c lxc:/// start $lxc - # manually run dhclient in guest - somehow this network won't start on its own - virsh -c lxc:/// lxc-enter-namespace $lxc /bin/bash -c "dhclient $VIF_GUEST" - fi - else - post_install_myplc $lxc $personality - if [ -n "$START_VM" ] ; then - virsh -c lxc:/// start $lxc - # it sounds like we don't need ssh per se any more - # it still makes sense to wait for network readiness though - # some day maybe... + # post install hook + [ -n "$NAT_MODE" ] && post_install_natip $lxc $personality || post_install_myplc $lxc $personality + # start the VM unless specified otherwise + if [ -n "$START_VM" ] ; then + echo Starting guest $lxc + virsh -c lxc:/// start $lxc + if [ -n "$NAT_MODE" ] ; then wait_for_ssh $lxc + else + wait_for_ssh $lxc $GUEST_IP fi fi } -function post_install_build () { +function post_install_natip () { set -x set -e @@ -670,7 +670,7 @@ function post_install_build () { ### From myplc-devel-native.spec # be careful to backslash $ in this, otherwise it's the root context that's going to do the evaluation - cat << EOF | chroot $lxc_root bash -x + cat << EOF | chroot ${lxc_root} $personality bash -x # customize root's prompt /bin/cat << PROFILE > /root/.profile @@ -690,7 +690,7 @@ function post_install_myplc () { personality=$1; shift # be careful to backslash $ in this, otherwise it's the root context that's going to do the evaluation - cat << EOF | chroot $lxc_root bash -x + cat << EOF | chroot ${lxc_root} $personality bash -x # create /etc/sysconfig/network if missing [ -f /etc/sysconfig/network ] || /bin/echo NETWORKING=yes > /etc/sysconfig/network @@ -706,31 +706,52 @@ PROFILE EOF } +# workaround for broken lxc-enter-namespace +# relies on virsh net-dhcp-leases +# when successful we store result in /vservers//ipv4 +# because the lease expires afer a while +function guest_ipv4_cached_or_from_virsh_leases() { + lxc=$1; shift + network=default + + # place to cache result + cache=/vservers/$lxc/ipv4 + ipv4=$(cat $cache 2> /dev/null) + [ -z "$ipv4" ] && ipv4=$(virsh net-dhcp-leases $network | sed -e 's, *, ,g' | grep " $lxc " | grep ipv4 | cut -d' ' -f6 | cut -d/ -f1) + echo $ipv4 + # cache if needed + [ -n "$ipv4" -a ! -f $cache ] && echo $ipv4 > $cache + # always return 0 + return 0 +} + function wait_for_ssh () { set -x set -e - #trap failure ERR INT lxc=$1; shift - - echo network in guest is up, waiting for ssh... + + # if run in public_ip mode, we know the IP of the guest and it is specified here + guest_ip=$1; shift #wait max 2 min for sshd to start - ssh_up="" + success="" current_time=$(date +%s) stop_time=$(($current_time + 120)) counter=1 while [ "$current_time" -lt "$stop_time" ] ; do echo "$counter-th attempt to reach sshd in container $lxc ..." - ssh -o "StrictHostKeyChecking no" $GUEST_IP 'uname -i' && { ssh_up=true; echo "SSHD in container $lxc is UP"; break ; } || : - sleep 10 - current_time=$(($current_time + 10)) + [ -z "$guest_ip" ] && guest_ip=$(guest_ipv4_cached_or_from_virsh_leases $lxc) + [ -n "$guest_ip" ] && ssh -o "StrictHostKeyChecking no" $guest_ip 'uname -i' && { + success=true; echo "SSHD in container $lxc is UP on IP $guest_ip"; break ; } || : counter=$(($counter+1)) + sleep 10 + current_time=$(date +%s) done # Thierry: this is fatal, let's just exit with a failure here - [ -z $ssh_up ] && { echo "SSHD in container $lxc is not running" ; exit 1 ; } + [ -z $success ] && { echo "SSHD in container $lxc could not be reached (guest_ip=$guest_ip)" ; exit 1 ; } return 0 } @@ -817,8 +838,8 @@ function main () { # check we've exhausted the arguments [[ -n "$@" ]] && usage - # BUILD_MODE is true unless we specified a hostname - [ -n "$GUEST_HOSTNAME" ] || BUILD_MODE=true + # NAT_MODE is true unless we specified a hostname + [ -n "$GUEST_HOSTNAME" ] || NAT_MODE=true # set default values [ -z "$fcdistro" ] && fcdistro=$DEFAULT_FCDISTRO @@ -831,14 +852,14 @@ function main () { # the set of preinstalled packages - depends on mode if [ -z "$PREINSTALLED" ] ; then - if [ -n "$BUILD_MODE" ] ; then + if [ -n "$NAT_MODE" ] ; then PREINSTALLED=devel.pkgs else PREINSTALLED=runtime.pkgs fi fi - if [ -n "$BUILD_MODE" ] ; then + if [ -n "$NAT_MODE" ] ; then # we can now set GUEST_HOSTNAME safely [ -z "$GUEST_HOSTNAME" ] && GUEST_HOSTNAME=$(echo $lxc | sed -e 's,\.,-,g') else @@ -867,7 +888,7 @@ function main () { # compute networking details for the test mode # (build mode relies entirely on dhcp on the private subnet) - if [ -z "$BUILD_MODE" ] ; then + if [ -z "$NAT_MODE" ] ; then #create_bridge_if_needed $PUBLIC_BRIDGE lbuild-bridge.sh $PUBLIC_BRIDGE @@ -882,7 +903,9 @@ function main () { setup_lxc $lxc $fcdistro $pldistro $personality - devel_or_vtest_tools $lxc $fcdistro $pldistro $personality + # historically this command is for setting up a build or a test VM + # kind of patchy right now though + devel_or_test_tools $lxc $fcdistro $pldistro $personality # container gets started here post_install $lxc $personality