diff options
author | 2015-04-14 14:48:11 +0200 | |
---|---|---|
committer | 2015-04-16 15:18:47 +0000 | |
commit | d2b1e4628ae701c5c220ff7dc98560af7d9855ae (patch) | |
tree | 657f2affd353a55aa625a42ae3ca13857d1d385d /fuel/prototypes/libvirt/deploy/functions | |
parent | 101550e036ca0dd7cc5bab0fc8e635062ac32138 (diff) |
Prototype of automated libvirt installation
This is a prototype to experiment with the DEA concept and
how to use it to automatically deploy a KVM environment using
libvirt.
It is now possible to perform a fully automated deploy from
an ISO file.
Highlights:
- Fully automated Fuel deploy installing three controllers,
two computes in full HA mode including Ceilometer
- create_dea.sh will create a DEA YAML file with an
existing deployment as template.
- The install will configure settings, networks and the
interface config of all nodes.
JIRA:
Change-Id: Icc8922afca8508c9062aa5be95e2482086a4f624
Signed-off-by: Stefan K. Berg <stefan.k.berg@ericsson.com>
Diffstat (limited to 'fuel/prototypes/libvirt/deploy/functions')
6 files changed, 354 insertions, 0 deletions
diff --git a/fuel/prototypes/libvirt/deploy/functions/common.sh b/fuel/prototypes/libvirt/deploy/functions/common.sh new file mode 100755 index 0000000..f6cceb4 --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/common.sh @@ -0,0 +1,109 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Common functions + +error_exit () { + echo "Error: $@" >&2 + exit 1 +} + +ssh() { + SSHPASS="r00tme" sshpass -e ssh -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no -o ConnectTimeout=15 "$@" +} + +scp() { + SSHPASS="r00tme" sshpass -e scp -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no -o ConnectTimeout=15 "$@" +} + +noNodesUp () { + fuel node | grep True | wc -l +} + +fuel () { + ssh root@10.20.0.2 "fuel $@" +} + +# Return MAC id for virsh node +getNodeId() { + virsh dumpxml $1 | grep "mac address" | head -1 | sed "s/.*'..:..:..:..:\(.*\)'.*/\1/" +} + +# Wait for node with virtid name to come up +waitForHost() { + mac=`getNodeId $1` + + while true + do + fuel node --node-id $mac 2>/dev/null | grep -q True && break + sleep 3 + echo -n "." + done + echo -e "\n" +} + +# Currently not used! +# Wait for node count to increase +waitForNode() { + local cnt + local initCnt + local expectCnt + + initCnt=`noNodesUp` + expectCnt=$[initCnt+1] + while true + do + cnt=`noNodesUp` + if [ $cnt -eq $expectCnt ]; then + break + elif [ $cnt -lt $initCnt ]; then + error_exit "Node count decreased while waiting, $initCnt -> $cnt" + elif [ $cnt -gt $expectCnt ]; then + error_exit "Node count exceeded expect count, $cnt > $expectCnt" + fi + sleep 3 + echo -n "." + done + echo -e "\n" +} + +bootorder_dvdhd() { + virsh dumpxml $1 | grep -v "<boot.*>" | \ + sed "/<\/os>/i\ + <boot dev='cdrom'/\>\n\ + <boot dev='hd'/\>\n\ + <bootmenu enable='no'/\>" > $tmpdir/vm.xml || error_exit "Could not set bootorder" + virsh define $tmpdir/vm.xml || error_exit "Could not set bootorder" +} + +bootorder_hddvd() { + virsh dumpxml $1 | grep -v "<boot.*>" | \ + sed "/<\/os>/i\ + <boot dev='hd'/\>\n\ + <boot dev='cdrom'/\>\n\ + <bootmenu enable='no'/\>" > $tmpdir/vm.xml || error_exit "Could not set bootorder" + virsh define $tmpdir/vm.xml || error_exit "Could not set bootorder" +} + +addisofile() { + virsh dumpxml $1 | grep -v '\.iso' | sed "s/<.*device='cdrom'.*/<disk type='file' device='cdrom'>/" | \ + sed "/<.*device='cdrom'.*/a <source file='$2'/>" > $tmpdir/vm.xml \ + || error_exit "Could not add isofile" + virsh define $tmpdir/vm.xml || error_exit "Could not add isofile" +} + +removeisofile() { + virsh dumpxml $1 | grep -v '\.iso' | sed "s/<.*device='cdrom'.*/<disk type='block' device='cdrom'>/" \ + > $tmpdir/vm.xml \ + || error_exit "Could not remove isofile" + virsh define $tmpdir/vm.xml || error_exit "Could not remove isofile" +} diff --git a/fuel/prototypes/libvirt/deploy/functions/deploy_env.sh b/fuel/prototypes/libvirt/deploy/functions/deploy_env.sh new file mode 100755 index 0000000..6fb26c4 --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/deploy_env.sh @@ -0,0 +1,81 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Deploy! + +scp -q $deafile root@10.20.0.2:. || error_exit "Could not copy DEA file to Fuel" +echo "Uploading build tools to Fuel server" +ssh root@10.20.0.2 rm -rf tools || error_exit "Error cleaning old tools structure" +scp -qrp $topdir/tools root@10.20.0.2:. || error_exit "Error copying tools" + +# Refuse to run if environment already present +envcnt=`fuel env | tail -n +3 | grep -v '^$' | wc -l` +if [ $envcnt -ne 0 ]; then + error_exit "Environment count is $envcnt" +fi + +# Refuse to run if any nodes are up +nodeCnt=`noNodesUp` +if [ $nodeCnt -ne 0 ]; then + error_exit "Nodes are up (node count: $nodeCnt)" +fi + +# Extract release ID for Ubuntu environment +ubuntucnt=`fuel release | grep Ubuntu | wc -l` +if [ $ubuntucnt -ne 1 ]; then + error_exit "Not exacly one Ubuntu release found" +fi + +ubuntuid=`fuel release | grep Ubuntu | awk '{ print $1 }'` + +# Create environment +fuel env create --name Foobar --rel $ubuntuid --mode ha --network-mode neutron --net-segment-type vlan || error_exit "Error creating environment" +envId=`ssh root@10.20.0.2 fuel env | tail -n +3 | awk '{ print $1 }'` || error_exit "Could not get environment id" + + +echo "Running transplant #1" +ssh root@10.20.0.2 "cd tools; ./transplant1.sh ../`basename $deafile`" || error_exit "Error running transplant sequence #1" + +# Spin up VMs +for node in controller1 controller2 controller3 compute4 compute5 +do + echo "Starting VM $node" + virsh start $node >/dev/null 2>&1 || error_exit "Could not virsh start $node" + sleep 10 +done + +for node in controller1 controller2 controller3 +do + echo -n "Waiting for Fuel to detect $node" + waitForHost $node + echo "Setting role for $node" + fuel node set --node-id `getNodeId $node` --role controller,mongo --env $envId || error_exit "Could not set role for $node" +done + +for node in compute4 compute5 +do + echo -n "Waiting for Fuel to detect $node" + waitForHost $node + echo "Setting role for $node" + fuel node set --node-id `getNodeId $node` --role compute --env $envId || error_exit "Could not set role for $node" +done + +# Inject node network config +echo "Running transplant #2" +ssh root@10.20.0.2 "cd tools; ./transplant2.sh ../`basename $deafile`" || error_exit "Error running transplant sequence #2" + +# Run pre-deploy with default input +# Need to set terminal as script does "clear" +ssh root@10.20.0.2 "TERM=vt100 /opt/opnfv/pre-deploy.sh < /dev/null" || error_exit "Pre-deploy failed" + +# Deploy +echo "Deploying!" +ssh root@10.20.0.2 "fuel deploy-changes --env $envId" >/dev/null 2>&1 || error_exit "Deploy failed" +echo "Deployment completed" diff --git a/fuel/prototypes/libvirt/deploy/functions/install_iso.sh b/fuel/prototypes/libvirt/deploy/functions/install_iso.sh new file mode 100755 index 0000000..0a92cd5 --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/install_iso.sh @@ -0,0 +1,62 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Recreate disk - needed for the reboot to work +fueldisk=`virsh dumpxml fuel-master | \ + grep fuel-master.raw | sed "s/.*'\(.*\)'.*/\1/"` +disksize=`ls -l $fueldisk | awk '{ print $5 }'` +rm -f $fueldisk +fallocate -l $disksize $fueldisk + +bootorder_hddvd fuel-master +sleep 3 +addisofile fuel-master $isofile +sleep 3 +virsh start fuel-master + +# wait for node up +echo "Waiting for Fuel master to accept SSH" +while true +do + ssh root@10.20.0.2 date 2>/dev/null + if [ $? -eq 0 ]; then + break + fi + sleep 10 +done + +# Wait until fuelmenu is up +echo "Waiting for fuelmenu to come up" +menuPid="" +while [ -z "$menuPid" ] +do + menuPid=`ssh root@10.20.0.2 "ps -ef" 2>&1 | grep fuelmenu | grep -v grep | awk '{ print $2 }'` + sleep 10 +done + +# This is where we would inject our own astute.yaml + +echo "Found menu as PID $menuPid, now killing it" +ssh root@10.20.0.2 "kill $menuPid" 2>/dev/null + +# Wait until installation complete +echo "Waiting for bootstrap of Fuel node to complete" +while true +do + ssh root@10.20.0.2 "ps -ef" 2>/dev/null \ + | grep -q /usr/local/sbin/bootstrap_admin_node + if [ $? -ne 0 ]; then + break + fi + sleep 10 +done + +echo "Waiting two minutes for Fuel to stabilize" +sleep 2m diff --git a/fuel/prototypes/libvirt/deploy/functions/isolinux.cfg.patch b/fuel/prototypes/libvirt/deploy/functions/isolinux.cfg.patch new file mode 100644 index 0000000..298a057 --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/isolinux.cfg.patch @@ -0,0 +1,14 @@ +*** isolinux/isolinux.cfg.orig 2015-04-15 08:29:52.026868322 -0400 +--- isolinux/isolinux.cfg 2015-04-15 08:30:34.350868343 -0400 +*************** +*** 19,22 **** + menu label Fuel Install (^Static IP) + menu default + kernel vmlinuz +! append initrd=initrd.img biosdevname=0 ks=cdrom:/ks.cfg ip=10.20.0.2 gw=10.20.0.1 dns1=10.20.0.1 netmask=255.255.255.0 hostname=fuel.domain.tld showmenu=no +--- 19,22 ---- + menu label Fuel Install (^Static IP) + menu default + kernel vmlinuz +! append initrd=initrd.img biosdevname=0 ks=cdrom:/ks.cfg ip=10.20.0.2 gw=10.20.0.1 dns1=10.20.0.1 netmask=255.255.255.0 hostname=fuel.domain.tld showmenu=yes + diff --git a/fuel/prototypes/libvirt/deploy/functions/ks.cfg.patch b/fuel/prototypes/libvirt/deploy/functions/ks.cfg.patch new file mode 100644 index 0000000..1896957 --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/ks.cfg.patch @@ -0,0 +1,19 @@ +*** ks.cfg.orig Wed Apr 15 21:47:09 2015 +--- ks.cfg Wed Apr 15 21:47:24 2015 +*************** +*** 35,41 **** + default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + + installdrive="undefined" +! forceformat="no" + for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + + set ${drives} ${removable_drives} +--- 35,41 ---- + default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + + installdrive="undefined" +! forceformat="yes" + for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + + set ${drives} ${removable_drives} diff --git a/fuel/prototypes/libvirt/deploy/functions/patch-iso.sh b/fuel/prototypes/libvirt/deploy/functions/patch-iso.sh new file mode 100755 index 0000000..782737e --- /dev/null +++ b/fuel/prototypes/libvirt/deploy/functions/patch-iso.sh @@ -0,0 +1,69 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# This is a temporary script - this should be rolled into a separate +# build target "make ci-iso" instead! + +exit_handler() { + rm -Rf $tmpnewdir + fusermount -u $tmporigdir 2>/dev/null + test -d $tmporigdir && mdir $tmporigdir +} + +trap exit_handler exit + +error_exit() { + echo "$@" + exit 1 +} + + +top=$(cd `dirname $0`; pwd) +origiso=$(cd `dirname $1`; echo `pwd`/`basename $1`) +newiso=$(cd `dirname $2`; echo `pwd`/`basename $2`) +tmpdir=$3 +tmporigdir=/${tmpdir}/origiso +tmpnewdir=/${tmpdir}/newiso + +test -f $origiso || error_exit "Could not find origiso $origiso" +test -d $tmpdir || error_exit "Could not find tmpdir $tmpdir" + + +if [ "`whoami`" != "root" ]; then + error_exit "You need be root to run this script" +fi + +echo "Copying..." +rm -Rf $tmporigdir $tmpnewdir +mkdir -p $tmporigdir $tmpnewdir +fuseiso $origiso $tmporigdir || error_exit "Failed fuseiso" +cd $tmporigdir +find . | cpio -pd $tmpnewdir +cd $tmpnewdir +fusermount -u $tmporigdir +rmdir $tmporigdir +chmod -R 755 $tmpnewdir + +echo "Patching..." +cd $tmpnewdir +# Patch ISO to make it suitable for automatic deployment +cat $top/ks.cfg.patch | patch -p0 || error_exit "Failed patch 1" +cat $top/isolinux.cfg.patch | patch -p0 || error_exit "Failed patch 2" +rm -rf .rr_moved + +echo "Creating iso $newiso" +mkisofs -quiet -r \ + -J -R -b isolinux/isolinux.bin \ + -no-emul-boot \ + -boot-load-size 4 -boot-info-table \ + --hide-rr-moved \ + -x "lost+found" -o $newiso . || error_exit "Failed making iso" + |