summaryrefslogtreecommitdiffstats
path: root/fuel/prototypes/libvirt/deploy
diff options
context:
space:
mode:
authorStefan K. Berg <stefan.k.berg@ericsson.com>2015-04-14 14:48:11 +0200
committerStefan Berg <stefan.k.berg@ericsson.com>2015-04-16 15:18:47 +0000
commitd2b1e4628ae701c5c220ff7dc98560af7d9855ae (patch)
tree657f2affd353a55aa625a42ae3ca13857d1d385d /fuel/prototypes/libvirt/deploy
parent101550e036ca0dd7cc5bab0fc8e635062ac32138 (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')
-rwxr-xr-xfuel/prototypes/libvirt/deploy/deploy.sh98
-rwxr-xr-xfuel/prototypes/libvirt/deploy/functions/common.sh109
-rwxr-xr-xfuel/prototypes/libvirt/deploy/functions/deploy_env.sh81
-rwxr-xr-xfuel/prototypes/libvirt/deploy/functions/install_iso.sh62
-rw-r--r--fuel/prototypes/libvirt/deploy/functions/isolinux.cfg.patch14
-rw-r--r--fuel/prototypes/libvirt/deploy/functions/ks.cfg.patch19
-rwxr-xr-xfuel/prototypes/libvirt/deploy/functions/patch-iso.sh69
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant1.sh67
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant2.sh80
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant_interfaces.py66
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant_network_scheme.py42
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant_network_settings.py52
-rwxr-xr-xfuel/prototypes/libvirt/deploy/tools/transplant_settings.py36
13 files changed, 795 insertions, 0 deletions
diff --git a/fuel/prototypes/libvirt/deploy/deploy.sh b/fuel/prototypes/libvirt/deploy/deploy.sh
new file mode 100755
index 0000000..7eff3da
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/deploy.sh
@@ -0,0 +1,98 @@
+#!/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
+##############################################################################
+
+# Setup locations
+topdir=$(cd `dirname $0`; pwd)
+exampledir=$(cd $topdir/../examples; pwd)
+functions=${topdir}/functions
+tmpdir=$HOME/fueltmp
+deployiso=${tmpdir}/deploy.iso
+
+# Define common functions
+. ${functions}/common.sh
+
+exit_handler() {
+ # Remove safety catch
+ kill $killpid
+}
+
+####### MAIN ########
+
+if [ "`whoami`" != "root" ]; then
+ error_exit "You need be root to run this script"
+fi
+
+if [ $# -eq 0 -o $# -gt 2 ]; then
+ error_exit "Argument error"
+fi
+
+# Setup tmpdir
+if [ -d $tmpdir ]; then
+ rm -Rf $tmpdir || error_exit "Coul not remove tmpdir $tmpdir"
+fi
+
+mkdir $tmpdir || error_exit "Could not create tmpdir $tmpdir"
+
+if [ ! -f $1 ]; then
+ error_exit "Could not find ISO file $1"
+else
+ isofile=$(cd `dirname $1`; echo `pwd`/`basename $1`)
+fi
+
+# If no DEA specified, use the example one
+if [ $# -eq 1 ]; then
+ deafile=${exampledir}/libvirt_dea.yaml
+else
+ deafile=$(cd `dirname $2`; echo `pwd`/`basename $2`)
+fi
+
+if [ ! -f $deafile ]; then
+ error-exit "Could not find DEA file $deafile"
+fi
+
+
+# Enable safety catch at three hours
+(sleep 3h; kill $$) &
+killpid=$!
+
+# Enable exit handler
+trap exit_handler exit
+
+
+# Stop all VMs
+for node in controller1 controller2 controller3 compute4 compute5 fuel-master
+do
+ virsh destroy $node >/dev/null 2>&1
+done
+
+# Install the Fuel master
+# (Convert to functions at later stage)
+echo "Patching iso file"
+${functions}/patch-iso.sh $isofile $deployiso $tmpdir || error_exit "Failed to patch ISO"
+# Swap isofiles from now on
+isofile=$deployiso
+. ${functions}/install_iso.sh
+. ${functions}/deploy_env.sh
+
+echo "Waiting for two minutes for deploy to stabilize"
+sleep 2m
+
+echo "Verifying node status after deployment"
+set -o pipefail
+# Any node with non-ready status?
+ssh root@10.20.0.2 fuel node | tail -n +3 | cut -d "|" -f 2 | \
+ sed 's/ //g' | grep -v ready | wc -l | grep -q "^0$"
+if [ $? -ne 0 ]; then
+ error_exit "Deployment failed verification"
+else
+ echo "Deployment verified"
+fi
+
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"
+
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant1.sh b/fuel/prototypes/libvirt/deploy/tools/transplant1.sh
new file mode 100755
index 0000000..9cead7a
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant1.sh
@@ -0,0 +1,67 @@
+#!/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
+##############################################################################
+
+cleanup () {
+ if [ -n "$tmpDir" ]; then
+ rm -Rf $tmpDir
+ fi
+}
+
+trap cleanup exit
+
+error_exit () {
+ echo "Error: $@" >&2
+ exit 1
+}
+
+tmpDir=`mktemp -d /tmp/deaXXXX`
+
+export PATH=`dirname $0`:$PATH
+
+if [ $# -lt 1 ]; then
+ error_exit "Argument error"
+fi
+deafile=$1
+shift
+
+if [ $# -ne 0 ]; then
+ comment="$@"
+fi
+
+if [ ! -f "$deafile" ]; then
+ error_exit "Can't find $deafile"
+fi
+
+if [ `fuel env | tail -n +3 | grep -v '^$' | wc -l` -ne 1 ]; then
+ error_exit "Not exactly one environment"
+fi
+envId=`fuel env | tail -n +3 | grep -v '^$' | awk '{ print $1 }'`
+
+fuel settings --env $envId --download --dir $tmpDir > /dev/null || \
+ error_exit "Could not get settings"
+fuel network --env $envId --download --dir $tmpDir > /dev/null || \
+ error_exit "Could not get network settings"
+
+cp $tmpDir/network_${envId}.yaml network_before.yaml
+transplant_network_settings.py $tmpDir/network_${envId}.yaml $deafile || \
+ error_exit "Could not transplant network settings"
+fuel network --env $envId --upload --dir $tmpDir || \
+ error_exit "Could not update network settings"
+cp $tmpDir/network_${envId}.yaml network_after.yaml
+
+cp $tmpDir/settings_${envId}.yaml settings_before.yaml
+transplant_settings.py $tmpDir/settings_${envId}.yaml $deafile || \
+ error_exit "Could not transplant settings"
+fuel settings --env $envId --upload --dir $tmpDir || \
+ error_exit "Could not update settings"
+cp $tmpDir/settings_${envId}.yaml settings_after.yaml
+
+
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant2.sh b/fuel/prototypes/libvirt/deploy/tools/transplant2.sh
new file mode 100755
index 0000000..5049f88
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant2.sh
@@ -0,0 +1,80 @@
+#!/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
+##############################################################################
+
+cleanup () {
+ if [ -n "$tmpDir" ]; then
+ rm -Rf $tmpDir
+ fi
+}
+
+trap cleanup exit
+
+error_exit () {
+ echo "Error: $@" >&2
+ exit 1
+}
+
+tmpDir=`mktemp -d /tmp/deaXXXX`
+
+export PATH=`dirname $0`:$PATH
+
+if [ $# -ne 1 ]; then
+ error_exit "Argument error"
+fi
+deaFile=$1
+
+if [ ! -f "$deaFile" ]; then
+ error_exit "Can't find $deaFile"
+fi
+
+
+if [ `fuel env | tail -n +3 | grep -v '^$' | wc -l` -ne 1 ]; then
+ error_exit "Not exactly one environment"
+fi
+envId=`fuel env | tail -n +3 | grep -v '^$' | awk '{ print $1 }'`
+
+# Phase 1: Graft deployment information
+if [ "a" == "b" ]; then
+fuel deployment --env $envId --default --dir $tmpDir || \
+ error_exit "Could not dump environment"
+
+for controller in `find $tmpDir -type f | grep -v compute`
+do
+ transplant_network_scheme.py $controller $deaFile controller || \
+ error_exit "Failed to graft `basename $controller`"
+done
+
+for compute in `find $tmpDir -type f | grep compute`
+do
+ transplant_network_scheme.py $compute $deaFile compute || \
+ error_exit "Failed to graft `basename $compute`"
+done
+
+fuel deployment --env $envId --upload --dir $tmpDir || \
+ error_exit "Could not upload environment"
+fi
+# Phase 2: Graft interface information
+
+for nodeId in `fuel node | grep True | awk '{ print $1}'`
+do
+ echo "Node $nodeId"
+ fuel node --node-id $nodeId --network --download --dir $tmpDir || \
+ error_exit "Could not download node $nodeId"
+
+ transplant_interfaces.py ${tmpDir}/node_${nodeId}/interfaces.yaml $deaFile || \
+ error_exit "Failed to graft interfaces"
+
+ fuel node --node-id $nodeId --network --upload --dir $tmpDir || \
+ error_exit "Could not upload node $nodeId"
+done
+
+
+
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant_interfaces.py b/fuel/prototypes/libvirt/deploy/tools/transplant_interfaces.py
new file mode 100755
index 0000000..8d076ff
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant_interfaces.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+##############################################################################
+# 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
+##############################################################################
+
+import yaml
+import re
+import sys
+import os
+
+if len(sys.argv) != 3:
+ sys.stderr.write("Usage: "+sys.argv[0]+" <infile> <deafile>\n")
+ sys.exit(1)
+
+infile = sys.argv[1]
+if not os.path.exists(infile):
+ sys.stderr.write("ERROR: The file "+infile+" could not be opened\n")
+ sys.exit(1)
+
+deafile = sys.argv[2]
+if not os.path.exists(deafile):
+ sys.stderr.write("ERROR: The file "+deafile+" could not be opened\n")
+ sys.exit(1)
+deafile = sys.argv[2]
+
+namespace = "interfaces"
+
+f1 = open(infile, 'r')
+doc1 = yaml.load(f1)
+f1.close()
+
+f2 = open(deafile, 'r')
+doc2 = yaml.load(f2)
+f2.close()
+
+# Create lookup table network name -> id for current setup
+nwlookup = {}
+for interface in doc1:
+ iface = {}
+ networks = []
+ for network in interface["assigned_networks"]:
+ nwlookup[network["name"]] = network["id"]
+
+
+out = {}
+out["interfaces"] = {}
+
+for interface in doc1:
+ assigned = []
+ nw = {}
+ interface["assigned_networks"] = []
+ for nwname in doc2["interfaces"][interface["name"]]:
+ iface = {}
+ iface["id"] = nwlookup[nwname]
+ iface["name"] = nwname
+ interface["assigned_networks"].append(iface)
+
+f3 = open(infile, 'w')
+f3.write(yaml.dump(doc1, default_flow_style=False))
+f3.close()
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant_network_scheme.py b/fuel/prototypes/libvirt/deploy/tools/transplant_network_scheme.py
new file mode 100755
index 0000000..7d50cbe
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant_network_scheme.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+##############################################################################
+# 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
+##############################################################################
+
+import yaml
+import re
+import sys
+import os
+
+if len(sys.argv) != 4:
+ sys.stderr.write("Usage: "+sys.argv[0]+" <file> <deafile> [compute|controller]\n")
+ sys.exit(1)
+
+file = sys.argv[1]
+if not os.path.exists(file):
+ sys.stderr.write("ERROR: The file "+file+" could not be opened\n")
+ sys.exit(1)
+
+deafile = sys.argv[2]
+namespace = sys.argv[3]
+
+f1 = open(file, 'r')
+doc1 = yaml.load(f1)
+f1.close()
+
+f2 = open(deafile, 'r')
+doc2 = yaml.load(f2)
+f1.close()
+
+doc1["network_scheme"]["transformations"] = doc2[namespace]
+
+f2 = open(file, 'w')
+f2.write(yaml.dump(doc1, default_flow_style=False))
+f2.close()
+
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant_network_settings.py b/fuel/prototypes/libvirt/deploy/tools/transplant_network_settings.py
new file mode 100755
index 0000000..c0a46be
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant_network_settings.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+##############################################################################
+# 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
+##############################################################################
+
+import yaml
+import re
+import sys
+import os
+
+if len(sys.argv) != 3:
+ sys.stderr.write("Usage: "+sys.argv[0]+" <file> <deafile>\n")
+ sys.exit(1)
+
+file = sys.argv[1]
+if not os.path.exists(file):
+ sys.stderr.write("ERROR: The file "+file+" could not be opened\n")
+ sys.exit(1)
+
+deafile = sys.argv[2]
+if not os.path.exists(deafile):
+ sys.stderr.write("ERROR: The file "+deafile+" could not be opened\n")
+ sys.exit(1)
+
+f1 = open(file, 'r')
+doc1 = yaml.load(f1)
+f1.close()
+
+f2 = open(deafile, 'r')
+doc2 = yaml.load(f2)
+f2.close()
+
+# Grab IDs from Fuel version, graft onto DEA version and save
+id = []
+groupid = []
+for nw in doc1["networks"]:
+ id.append(nw["id"])
+ groupid.append(nw["group_id"])
+
+for nw in doc2["network"]["networks"]:
+ nw["id"] = id.pop(0)
+ nw["group_id"] = groupid.pop(0)
+
+f3 = open(file, 'w')
+f3.write(yaml.dump(doc2["network"], default_flow_style=False))
+f3.close()
diff --git a/fuel/prototypes/libvirt/deploy/tools/transplant_settings.py b/fuel/prototypes/libvirt/deploy/tools/transplant_settings.py
new file mode 100755
index 0000000..7f5c0d8
--- /dev/null
+++ b/fuel/prototypes/libvirt/deploy/tools/transplant_settings.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+##############################################################################
+# 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
+##############################################################################
+
+import yaml
+import re
+import sys
+import os
+
+if len(sys.argv) != 3:
+ sys.stderr.write("Usage: "+sys.argv[0]+" <file> <deafile>\n")
+ sys.exit(1)
+
+file = sys.argv[1]
+if not os.path.exists(file):
+ sys.stderr.write("ERROR: The file "+file+" could not be opened\n")
+ sys.exit(1)
+
+deafile = sys.argv[2]
+
+f1 = open(deafile, 'r')
+doc = yaml.load(f1)
+f1.close()
+
+out = doc["settings"]
+f2 = open(file, 'w')
+f2.write(yaml.dump(out, default_flow_style=False))
+f2.close()
+