########################################### ### Instructions to use SnapVMX on ESXi ### ########################################### ### 1. Move or copy this file to /tmp/ ### 2. Copy and paste these two lines in the ESXi console SnapVMX () { sh /tmp/SnapVMX.source.code.ESXi_version.txt "SnapVMX \"$1\""; }; SnapTree () { sh /tmp/SnapVMX.source.code.ESXi_version.txt "SnapTree \"$1\""; }; ### 3. Now you are ready to use both functions as you would do with ESX classic. #------------------------------------------------------------------------- # Copyright (C) 2009, 2010 Ruben Miguelez Garcia # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #------------------------------------------------------------------------- #-------- Helper functions -------------------- CID () { grep -i '^CID' "$1" | awk -F'=' '{ print $2 }'; }; ParentCID () { grep -i '^parentCID' "$1" | awk -F'=' '{ print $2 }'; }; ParentFile () { grep -i '^parentFileNameHint' "$1" | awk -F'"' '{ print $2 }'; }; Size () { ls -l "$1" | awk '{ print $5 }' ; }; SizeH () { ls -lh "$1" | awk '{ print $5 }'; }; DeltaOrFlat () { FPATH=`dirname "$1"`; echo -n "$FPATH/" ; grep -i '^RW' "$1" | awk -F'"' '{ print $2 }'; }; FileExists () { if [ -s "$1" ] ; then echo "true"; else echo "false" ; fi; }; SizeNeeded () { # Usage: SizeNeeded [SnapN, SnapN-1,....,Snap2,Snap1,BaseDisk] # Example: SizeNeeded [1,2,1,2,20,50] python -c "R=$1; BD=R[-1]; R=R[:-1]; L=len(R)-1; SU=SN=0; for i in range(L): SU=min(((SU or R[i])+R[i+1]),BD); SN=(SU-R[i+1])*((SU-R[i+1])>0)+SN; #print 'Array of snapshots: ', R,'-- Base Disk: ',BD,' -- Space Needed: ', SN; R_MB=SN/(1024.0*1024);R_GB=R_MB/1024; print '%.2f Megabytes = %.2f Gigabytes' % (R_MB,R_GB) ;" ;} CID_chain_check () { # Usage: CID_chain_check FILE.vmdk # Check the CID chain between FILE.vmdk and its parent and display the result (null if no mismatch) FILE="$1"; FILE_PARENT=`ParentFile "$FILE"`; if [ `ParentCID "$FILE"` != `CID "$FILE_PARENT"` ]; then echo -n "-- Warning: CID chain mismatch between \"$FILE\" and \"$FILE_PARENT\""; fi; } #------- SnapTree -------------------------------------------------------- SnapTree () { # Usage: SnapTree FILE.vmdk # Follow the chain of files from FILE.vmdk down to the BaseDisk displaying them. FILE=$1; TAB=""; SIZES="[ "; HAS_SNAPSHOTS="0"; if [ `FileExists "$FILE"` = "false" ]; then echo "File \"$FILE\" not found. Exiting."; return -1 ; fi; # While the file is not the base disk while [ `ParentCID "$FILE"` != "ffffffff" ]; do HAS_SNAPSHOTS="1"; # Get size of delta file DELTA=`DeltaOrFlat "$FILE"`; if [ `FileExists "$DELTA"` = "true" ]; then SIZE_H=`SizeH "$DELTA"`; SIZES=$SIZES`Size "$DELTA"`","; else SIZE_H="Unknown -- Warning: Delta file (\"$DELTA\") not found"; SIZES=$SIZES"0,"; fi; # Check parent file PARENT=`ParentFile "$FILE"`; if [ `FileExists "$PARENT"` = "true" ]; then # Check CID chain between this file and its parent RESULT_CID_chain_check=`CID_chain_check "$FILE"`; # Display file name and size in human format. If the CID is broken say it as well. echo -e "$TAB$FILE Size: $SIZE_H $RESULT_CID_chain_check" FILE=`ParentFile "$FILE"`; TAB=$TAB" "; else echo -e "$TAB$FILE Size: $SIZE_H -- Warning: Parent file (\"$PARENT\") not found. Unable to continue checking the chain of snapshots. Exiting."; return -1; fi; done; FLAT=`DeltaOrFlat "$FILE"`; SIZE_H=`SizeH "$FLAT"`; SIZES=$SIZES`Size "$FLAT"`"]"; echo -e "$TAB Base Disk: $FILE Size: $SIZE_H" if [ "$HAS_SNAPSHOTS" = "1" ] ; then echo 'Space needed on this Datastore to delete all the snapshots of this disk is: ' `SizeNeeded "$SIZES"`; fi; } #------- SnapVMX --------------------------------------------------------- SnapVMX () { # Usage: SnapVMX FILE.vmx # Extract the list of disks attached to the VM and pass them to the SnapTree function. if [ `FileExists "$1"` = "false" ]; then echo "VM Configuration file \"$1\" not found. Exiting." ; return -1; fi; # Get list of true SCSI SCSI_TRUE_LIST=`egrep -i '^scsi[0-9]+:[0-9]+.present = "true"' "$1" | awk -F'.' '{ print $1 }' `; # Go through the list of disks on the VM for SCSI in $SCSI_TRUE_LIST ; do # Get Disk name VMDK_VMX=`grep -i "^$SCSI.fileName" "$1" | awk -F'"' '{ print $2 }'` ; SnapTree "$VMDK_VMX"; echo "----------------"; done;} #------------------------------------------------------------------------- ## Execute the command provided as argument if [ "$1" != "" ]; then eval "$1"; fi;