ds2fullpath (){
sed -e 's/\[\([^]]\+\)\] \([^[ ]\+\)/\/vmfs\/volumes\/\1\/\2/'
}
get_ds_from_path (){
sed -e 's/\/vmfs\/volumes\/\([^\/]\+\)\/.*/\1/'
}
inner_quote (){
sed -e 's/[^"]*"\(.*\)".*/\1/'
}
get_allvms_vmid_name (){
vim-cmd vmsvc/getallvms | sed -e 's/\[.*\] .*//' -e 's/ \+$//' -e 's/\([0-9\]\+\) \+\(.*\)/\1 "\2"/' |
awk 'NR!=1'
}
get_allvms_vmid_datastore (){
vim-cmd vmsvc/getallvms | sed -e 's/\([0-9\]\+\) \+.* \+\[\(.*\)\] \(.*\/.*\.vmx\) \+.*/\1 "\2" "\3"/' |
awk 'NR!=1'
}
get_allvms_vmid_vmxpath (){
vim-cmd vmsvc/getallvms | sed -e 's/\([0-9\]\+\) \+.* \+\[\(.*\)\] \(.*\/.*\.vmx\) \+.*/\1 "[\2] \3"/' |
ds2fullpath |
awk 'NR!=1'
}
get_vmid_from_name (){
get_allvms_vmid_name | grep \"$1\" |awk '{print $1}'
}
get_vmxpath_from_vmid (){
get_allvms_vmid_vmxpath | awk '/^'$1' /{print $2}' | sed -e 's/^\"//' -e 's/\"$//'
}
get_vmxpath_from_name (){
vmid=`get_vmid_from_name $1`
get_vmxpath_from_vmid ${vmid}
}
get_vmsdpath_from_vmid (){
get_vmxpath_from_vmid $1 | sed -e 's/\.vmx$/.vmsd/'
}
get_datastore_from_vmid (){
get_allvms_vmid_datastore | awk '/^'$1' /{print $2}' | sed -e 's/^\"//' -e 's/\"$//'
}
get_vmname_from_vmid (){
get_allvms_vmid_name | grep "^$1 " | sed -e 's/.*"\(.*\)".*/\1/'
}
get_vmdk_data_file_from_vmdk (){
test -f "$1" || return
f=$(grep " \".*\.vmdk\"$" $1 | grep -v parentFileNameHint | sed -e 's/.* "\(.*\)"$/\1/')
echo "$f"|grep ^/ >/dev/null && echo "$f"
echo "$f"|grep ^/ >/dev/null || echo "`dirname "$1"`/$f"
}
is_there_snapshot (){
vmid=$1
snapshot_name=$2
vim-cmd vmsvc/snapshot.get $vmid | grep "\-\-Snapshot Name" | sed -e 's/-\+Snapshot Name \+: //' |
grep "$snapshot_name" >/dev/null
}
remove_last_snapshot (){
vmid=$1
if [ "`get_vmxpath_from_vmid $vmid`" = "" ] ; then return 255 ; fi
lv=`vim-cmd vmsvc/snapshot.get $vmid |grep CHILD |wc -l`
vim-cmd vmsvc/snapshot.remove $vmid 0 $lv
}
get_alltaskids (){
vim-cmd vimsvc/task_list | grep vim.Task: | sed -e 's/.*vim.Task://' -e 's/,//' -e "s/'//"
}
get_taskids_from_vmid (){
vim-cmd vimsvc/task_list | grep vim.Task:haTask-$1 | sed -e 's/.*vim.Task://' -e 's/,//' -e "s/'//"
}
filter_running_taskids (){
while read taskid ; do
is_task_running $taskid && echo $taskid
done
}
get_running_alltaskids (){
get_alltaskids | filter_running_taskids
}
get_running_taskids_from_vmid (){
get_taskids_from_vmid $1 | filter_running_taskids
}
get_taskname_from_taskid (){
vim-cmd vimsvc/task_info $taskid | grep "name = " | sed -e 's/.*"\(.*\)".*/\1/'
}
is_there_running_task_vmid (){
get_running_taskids_from_vmid $1 | grep .
}
is_task_running (){
taskid=$1
vim-cmd vimsvc/task_info $taskid | grep 'state = "running",' >/dev/null
}
wait_while_task_running_vmid (){
while : ; do
taskid=`get_running_taskids_from_vmid $1 | head -1`
if [ "$taskid" == "" ] ; then break ; fi
echo waiting `get_vmname_from_vmid $1` `get_taskname_from_taskid $taskid`
sleep 3
done
}
path_r2a (){
echo `cd "$1" && pwd`
}
path_cut (){
src_dir=`path_r2a "$1"`
file=$2
basedir=$(dirname "$src_dir")
c=$(echo "$basedir" | wc -c)
echo "$file" | cut -c ${c}- | sed -e 's/^\///'
}
cp_dir_sparse (){
cp_prog=$1
SRC=`path_r2a "$2"`
DST=`echo "$3" | sed -e 's/\/$//'`
find "$SRC" -type f | while read a ; do
$cp_prog "$a" $DST/`path_cut "$SRC" "$a"`
done
}
get_datafiles_from_filelayout_with_vmdk_data (){
get_datafiles_from_filelayout $1 |
while read a ; do
echo "$a"
echo "$a"|grep \.vmdk$ >/dev/null && get_vmdk_data_file_from_vmdk "$a"
done
}
get_datafiles_from_filelayout (){
vim-cmd vmsvc/get.filelayout $1 |
grep "\"\[.*\] .*\..*\"" |
inner_quote |
ds2fullpath
}
get_vmx_dir (){
d=`get_vmxpath_from_vmid $1`
dirname "$d"
}
get_logfile_dir (){
vim-cmd vmsvc/get.filelayout $1 |sed -e 's/^ \+//'| grep "^logDirectory *=" | inner_quote | ds2fullpath
}
get_logfiles_from_filelayout (){
d=`get_logfile_dir $1`
vim-cmd vmsvc/get.filelayout $1 | sed -e ':a;$!N;$!b a;s/\n//g' |
sed -e 's/.*,.*logFile *=[^\[]\+\[\([^]]*\)\].*/\1/' -e 's/",/"\n/g' |
inner_quote |
while read a ; do
echo "$d/$a"
done
}
get_configfiles_from_filelayout (){
d=`get_vmx_dir $1`
vim-cmd vmsvc/get.filelayout $1 |
sed -e ':a;$!N;$!b a;s/\n//g' |
sed -e 's/.*,.*configFile *=[^\[]\+\[\([^]]*\)\].*/\1/' -e 's/",/"\n/g' |
inner_quote |
while read a ; do
echo "$d/$a"
done
}
get_allfiles_from_filelayout (){
sub (){
get_configfiles_from_filelayout $1
get_logfiles_from_filelayout $1
get_datafiles_from_filelayout_with_vmdk_data $1
}
sub $1 | sort | uniq
}
vmname="$1"
backupdir="$2"
copy_p="python -u cp_sparse.py"
vmid=`get_vmid_from_name "$vmname"`
vmx="`get_vmxpath_from_vmid $vmid`"
vmsd="`get_vmsdpath_from_vmid $vmid`"
vim-cmd vmsvc/snapshot.create $vmid __backup __backup 1 1
wait_while_task_running_vmid $vmid
vim-cmd vmsvc/snapshot.get $vmid
dupfile=0
get_allfiles_from_filelayout $vmid | while read a ; do
basename "$a"
done | sort | uniq -d | grep . >/dev/null && dupfile=1
get_allfiles_from_filelayout $vmid | while read a ; do
dst="$backupdir/$vmname"
if [ "$dupfile" = "1" ] ; then
ds="`echo "$a" | get_ds_from_path`"
dst="$backupdir/$vmname/$ds"
fi
$copy_p "$a" "$dst/`basename "$a"`"
done
remove_last_snapshot $vmid
wait_while_task_running_vmid $vmid
get_datafiles_from_filelayout $vmid | grep \.vmdk$ | while read a ; do
dst="$backupdir/$vmname"
if [ "$dupfile" = "1" ] ; then
ds="`echo "$a" | get_ds_from_path`"
dst="$backupdir/$vmname/$ds"
fi
$copy_p "$a" "$dst/`basename "$a"`"
done
get_datafiles_from_filelayout $vmid | sort | uniq | grep \.vmdk$ | while read a ; do
if [ "$dupfile" = "1" ] ; then
continue
fi
parent_path=`grep "^parentFileNameHint *=" "$a" |inner_quote`
echo "$parent_path" | grep "^/" >/dev/null || continue
vmdk=`basename "$parent_path"`
cat $a | sed -e 's/^\(parentFileNameHint *= *\)".*"/\1"'"$vmdk"'"/' > "$backupdir/$vmname/`basename $a`"
done