21 Jul 2009

Convert vmdk to vdi files

I am moving away from VMWare Server to VirtualBox. VMWare 2's web interface at first excited me, then I have realized that it depends on platform specific browser plugins. The result is an everywhere available control interface (as long as you have installed the plugin) with the awefull slowness of a web interface. So why not just install a client application which integrates into the platform, is fast and reliable I ask.


VirtualBox seems to fit my needs for a software testing server much better than Vmware Server 2.x.

Migration involves converting VMWare's vmdk disk images to VirtualBox's vdi images. Vmdk images are often split into several files (snapshots, 2GB size limit on NTFS) and mus therefore usually be consolidated into one file again.

Instructions below require some software packages to be installed, on a debian system:

$ sudo apt-get install qemu virtualbox-ose
And vmware must be installed of course. In the example below «multipart.vmdk» is the base file of the vmware image (usually some multipart-S00N.vmdk files would reside in the same directory), «flattened.vdi» is the result and can be used with VirtualBox.

#!/usr/bin/env bash
# $Id$

# debug=1

bin=(vmware-vdiskmanager \
vmware-vdiskmanager \
vmware-vdiskmanager \
qemu-img \
VBoxManage)
cmd=("%s -R %s " \
"%s -d %s " \
"%s -r %s -t 0 %s" \
"%s convert %s -O raw %s" \
"%s convertdd %s %s")
msg_ok=("1. Consistency check." \
"2. Defragment." \
"3. Flattened vmdk files into 1 file: flattened.vmdk" \
"4. Converted flattened.vmdk into raw image." \
"5. Converted raw image into a VirtualBox image (vdi).")
msg_nok=("Failed consistency check of vmware image." \
"Failed to defragment vmware image." \
"Failed to flatten vmdk file." \
"Failed to convert vmdk into raw image." \
"Failed to convert raw image into vdi.")
file_src=("%s.vmdk" "%s.vmdk" "%s.vmdk" "%s-flattened.vmdk" "%s-flattened.bin")
file_dst=("" "" "%s-flattened.vmdk" "%s-flattened.bin" "%s.vdi")

# parameter check
if [[ ! -z "$1" ]]; then
file=$(echo "$1" | sed -e 's/\.vmdk$//')
else
echo "usage: $0 <vmwareimage.vmdk>"
exit 1
fi

# check for required binaries
function isexecutable {
if [[ ! -x "$(which $1)" ]]; then
echo "'$1' is eighter not in your \$PATH, not executable or"
echo "not installed, aborting."
exit 2
fi
}
for (( c=0; c < ${#bin[@]}; c++ )); do
isexecutable "${bin[$c]}"
done

function err {
echo $1
exit 3
}

# run command
function runpart {
exec="$1"
msg_succcess="$2"
msg_error="$3"

echo "$msg_succcess "
echo " executing: $exec"
a=$($exec 2>&1) # && echo "$msg_succcess ($a)" || err "$msg_error"
if [[ $? = 0 ]]; then
echo " $a"
else
echo " Failed execution, aborting."
exit 4
fi
}

echo "Clenaing up ..."
[ -f $(printf "%s-flattened.vmdk" "$file") ] && \
rm $(printf "%s-flattened.vmdk" "$file")
[ -f $(printf "%s-flattened.bin" "$file") ] && \
rm $(printf "%s-flattened.bin" "$file")
[ -f $(printf "%s.vdi" "$file") ] && \
rm $(printf "%s.vdi" "$file")

cat <<EOT
Converting $file.vmdk to $file.vdi. This will take some time ...

EOT

#run all parts
for (( c=0; c < ${#bin[@]}; c++ )); do
from=$(printf "${file_src[$c]}" "$file")
to=$(printf "${file_dst[$c]}" "$file")
if [[ -z "$to" ]]; then
cm=$(printf "${cmd[$c]}" "${bin[$c]}" "$from")
else
cm=$(printf "${cmd[$c]}" "${bin[$c]}" "$from" "$to")
fi

if [[ -n $debug ]]; then
echo "$cm"
echo " ${msg_ok[$c]}"
echo " ${msg_nok[$c]}"
echo ""
continue;
fi

runpart "$cm" "${msg_ok[$c]}" "${msg_nok[$c]}"
done

cat <<EOT
Done. you may delete the following files:
$(printf "${file_dst[2]}" "$file")
$(printf "${file_dst[3]}" "$file")

EOT

exit 0;


That's it, «flattened.vdi» is the disk image for VirtualBox.

Most of the infos were found in the following thread in the VirtualBox forum.

No comments: