Wednesday, June 7, 2017

Automatic Backup of VMs on ODA X5-2

I was looking for the best practice to backup ODA X5-2 guest VMs and found this post on OTN. Got lots of helpful info, but did not find an automatic way to backup the VMs. It's an old post, so I post my solution here.  Credits to many people replied to the above post .


Ref: ODAVP: HowTo backup/restore your VM Guest (Doc ID 1633166.1)


# cat backupGuestVM.sh


#!/bin/bash
# backupGuestVM.sh
# Description: Used to backup guest VM and it's vDisk.
#
# Modification History
#   10/13/2016 jx  Created
#
#-------------------------------------------------------------------------------
if [ ! $# -gt 0 ]; then
    echo "Usage: $0 all"
    echo "   or: $0 [gVM1 | gVM1 gVM2 ...]"
    exit;
fi
# Variables and functions
lpCnt=0
ttlLp=100
secWait=20
arDir=/cloudfs/backup
#arDir=/u02/app/oracle/oradata/datfinmprod
srcDir=u01/app/sharedrepo
logFile=/tmp/backupGuestVM.log
execOakCmd() {
    local oakAct=$1
    local vmList=$2
    local pidList=""
    echo "local cmd: =$oakAct=, vmList: =$vmList=..." | tee -a $logFile
    for aVM in $vmList; do
        cmd="oakcli $oakAct vm $aVM"
        echo "cmd is: =$cmd=..." | tee -a $logFile
        $cmd &
        pidList="$pidList $!"
    done
    echo "oak cmd $oakAct waiting list: =$pidList=..." | tee -a $logFile
    wait $pidList
}
#------------------------------------------------------------------------------
# Create a timestamp in a logfile
echo "backup guest VMs started at `date`..." | tee $logFile
# Create backup directory
todayStr=`date +'%Y%m%d'`
[ ! -d "$arDir/$todayStr" ] && ( mkdir $arDir/$todayStr || exit )
inVMs=$*
echo "passed in these VMs: =$inVMs=..." | tee -a $logFile
# Check if the passed in VMs are valid resources
vmLst=$inVMs
allVMLst=$( oakcli show vm|cut -f 2 -|grep -v NAME|tr -s '\n' ' ' | xargs )
if [ "$inVMs" = "all" ]; then
    vmLst=$allVMLst
else
    for aVM in $inVMs; do
        echo "$allVMLst" | grep -i $aVM
        if [ ! $? -eq 0 ]; then
            vmLst=${vmLst/$aVM/}
        fi
    done
    vmLst=$( echo $vmLst | awk '{$1=$1};1' )
fi
echo "valid VM list =$vmLst=..." | tee -a $logFile

# vm list is not null or empty, continue....
#------------------------------------------------------------------------------
if [ ! -z "$vmLst" -a "$vmLst" != " " ]; then
    # stop all the guest VMs
    echo "stop all the vm start at `date`..." | tee -a $logFile
    execOakCmd "stop" "$vmLst"
    # make sure all the VMs are offline
    vmArr=( $vmLst )
    vmCnt=${#vmArr[@]}
    echo "vmCnt: =$vmCnt=..." | tee -a $logFile
    # to prevent infinite loop, loop only 100 times
    while [[ $vmCnt -gt 0 && $lpCnt -lt $ttlLp ]]; do
        lpCnt=$[$lpCnt+1]
        for aVM in $vmLst; do
            isOffln=$( oakcli show vm | grep $aVM | grep OFFLINE )
            vmStatus=$( echo $? )
            if [ "$vmStatus" = "1" ]; then
                echo "Waiting $secWait seconds for =$aVM= vm goes offline ..." | tee -a $logFile
                sleep $secWait
            else
                vmCnt=$[$vmCnt-1]
            fi
        done
        echo "Waiting loop, current count: =$lpCnt=..." | tee -a $logFile
    done
    echo "All VMs are now offline at `date`...lpCnt: =$lpCnt=, vmCnt: =$vmCnt=..." |tee -a $logFile
# All VMs in the list are offline, do backup now....
#-------------------------------------------------------------------------------
    pidLst=""
    echo "create archives start at `date`..." |tee -a $logFile
    for aVM in $vmLst; do
        vmRepo=$( oakcli show vm | grep -i $aVM | cut -f 7 | awk '{$1=$1};1' )
        echo "vm: =$aVM=, repo: =$vmRepo=..." | tee -a $logFile
        dirLst=$( dir -d /$srcDir/$vmRepo/.ACFS/snaps/*$aVM* )
        for aDir in $dirLst; do
            # tar file name
            arName=${aDir##*"/"}
            arName=${arName#"oakvdk_"}
            arFile="$arDir/$todayStr/$arName.tar.gz"
            # source directory
            inFile=${aDir#"/"}
            tarCmd="tar -czf $arFile -C / $inFile"
            echo "Starting tar command =$tarCmd=... " | tee -a $logFile
            $tarCmd &
            pidLst="$pidLst $!"
        done; # loop thru the directories this vm has, which could be vm itself and vdisks;
    done; # loop thru the vmList
    echo "tar waiting list: =$pidLst=..." | tee -a $logFile
    wait $pidLst
    echo "All backups are done. Time at `date`."  | tee -a $logFile
    # After all backup done, start the VMs again
    execOakCmd "start" "$vmLst"
fi; # vmLst is not null or space
echo "backup succeeded at `date`." | tee -a $logFile

No comments:

Post a Comment