#!/usr/bin/python
"""
VMFS undelete 2008
Written by Jacob Cherkas
jcherkas@vmware.com
absolutely no guarantee of any kind
VMware, Inc.
"""
import sys
import re
import getopt

sys.path.append('/usr/lib/vmware/python2.2/site-packages')
from vmware.undeletemods import parseVMX
from vmware.undeletemods import menu
from vmware.undeletemods import vm
from vmware.undeletemods import Disk
from vmware.undeletemods import Writer
from vmware.undeletemods import Restore


def backup():
    
    vms=[]
    disks=[]
    snapshotedVMs=[]
    registeredVMs=""
    vmList=[]
    vmToDiskMap=""
    parsed=None
    
    #debug
    #print "vms:%s\n disks=%s\n snapshotedVMs=%s\n registeredVMs=%s\n vmList=%s\n vmToDiskMap=%s\n parsed=%s\n" \
    #   %(vms,disks,snapshotedVMs,registeredVMs,vmList,vmToDiskMap,parsed)
    #debug

    registeredVMs=menu.Menu()                                        
    registeredVMs.displayMenu()                                           #print menu of all found vms 
    print "found ", registeredVMs.getNumVMS(), " vms"
    vmList=registeredVMs.getUserInput()
    
    #debug
    #print "vmList = %s" % (len(vmList))
    #debug 
    
    parsed=parseVMX.ParseVMX()   
    vmToDiskMap=parsed.lookForDisks(vmList)   
                                 #get a list of all lvm ids on this host
    #debug
    #print "vmList = %s: " % (vmList)
    #print vmToDiskMap
    #print "len of vmToDiskMap = %i" % (len(vmToDiskMap))
    #debug  

    i = 0
    t =0
    for eachvm in vmToDiskMap:
        #debug
        #print "vm: %s" % (eachvm)
        #debug
        vms.append(vm.VM(eachvm))                                    #create a vm obj for each selected vm
    
        for eachdisk in vmToDiskMap[eachvm].iteritems():
            disks.append(Disk.Disk(eachdisk))                        #create a disk for each disk in vm
            disks[t].setDiskPath(vms[i].baseURL)                     #set full path of each vmdk
            vmdkpath=disks[t].getFileName()                          #get full path of vmdk   
            rdm=disks[t].checkRDM(vmdkpath)                          #check of the disk is an rdm.
            if (rdm):
                print "\n*****WARNING*****\n%s is an Raw Disk.\nRaw Disks are not supported.\n%s will not be added to the backup..." % (vmdkpath,vmdkpath)
                #remove this disks from the array
                disks.pop()
                continue
            #debug
            disks[t].readSCSIAdapterType(disks[t].getFileName())     #get lsi or buslogic adapter type
            disks[t].setUUID(disks[t].getFileName())                 #set uuid for each device
            disks[t].readVMHBAs()                                    #get all vmhba devs for this disk and corresponding /dev devices
            t +=1
        
        vms[i].setDisks(disks)                                       #add disks objects to vm instance    
        disks=[]
        t=0                                                          #clear for next iteration
        i +=1
        
    #debug
    #print "vms:%s\n disks=%s\n snapshotedVMs=%s\n registeredVMs=%s\n vmList=%s\n vmToDiskMap=%s\n parsed=%s\n" \
    #    %(vms,disks,snapshotedVMs,registeredVMs,vmList,vmToDiskMap,parsed)
    #debug
    
    print "number of vms to backup %s" % (len(vms))
    return vms



def writeToDiskOBJ(vms):
##write out binary as python objects
    try:
        while (1):  
            print "Ready to write to data to disk"
            input=raw_input("Enter path and filename of where to save the recover log to:")
    
#validate path   
            try:
                fh=open(input,'w')
                fh.close()
                break
            except IOError ,e:
                print e
                sys.exit()
                       
        writer=Writer.writer(input)
        writer.open()
   
#iterate over vms
        for i in vms:
            
            #debug
            #print "Backing up %s VMs: Number of VMS %s" % (i,len(vms))
            #debug
            
            print "_"*40
            print "working on VM: "+ i.getName()
        
            
#---------------------------------------------------------------  """
#check if vm has a snapshot..snapshoted vms are not supported yet """  
#---------------------------------------------------------------  """
            print "Checking for VM Snapshots..."
            if i.getSnapShotState():
                print "VMs with snapshots are not currently supported.. skipping vm: %s" % i.getName()
                vms.remove(i) #remove VM from list of VMs to backup
                continue
        
            if (i.snapShotVM()):
                print "Creating Snapshot..."   
                for eachdisk in i.getDisks():
                    print 'read block list for %s' % eachdisk.getFileName() 
                    eachdisk.readBlockList()
            
            else:
                print "Could Not snapshot VM...Skipping.."
                print "VM %s will not be backuped up..." % i.getName()
                vms.remove(i) #remove VM from list of VMs to backup
                continue
        
            print "removing snapshot...."
            i.removeSnapShot()
            
        #check the size of vms. If it is empty do not write anything to disk
        if len(vms) == 0:
            print "Nothing to backup!!!!"
            writer.close
            
        else:
            writer.writeOBJ(vms)
            writer.close()
            print "Done......"
    
    except KeyboardInterrupt:
            print"\nAborting....."
            sys.exit()
            
       

def restore():
    
    while (1):
        try:
            oRead=raw_input("enter file name to restore from: ")
            try:
                fh=open(oRead,'rb')
                fh.close()
                break
            except IOError, e:
                print "Unable to open %s ,%s" % (oRead,e)
                print "Please make sure you enter the full path and file name\n" 
                print "Press ctrl-c to quit anytime!!!!!\n"
        
        except KeyboardInterrupt:
            print"\nAborting....."
            sys.exit()
    
    res=Restore.restore(oRead)
    res.readOBJ()
    res.selectRestorableVMS()
    res.selectDisktoRestore()
    res.selectRestoreDS()
    res.selectRestoreDIR()
    res.selectRestoreFile()
    res.restoreVM()
    

def start():
    
    while (1):
        print \
        """
        ########################################################
        #        VMFS Data Recovery and Backup                 #
        #                                                      #
        # This tool is NOT a replacement for regular backups   #
        # Please backup your data on a regular basis           #
        # There is absolutely no guarantee                     #
        # Use at your own risk                                 #
        #                                                      #
        # VMs with Raw Disks (virtual or physical) are         #
        # Not supported!!!!                                    # 
        ########################################################
        
        """
        
        try:
            print "-"*50
            option=raw_input("Select [b]ackup, [r]estore [q] to quit: ")
        except KeyboardInterrupt:
            print"\nAborting....."
            sys.exit()
            
        if re.search('b',option,re.IGNORECASE):
            map=backup()
            writeToDiskOBJ(map)
            
        if re.search('r',option,re.IGNORECASE):
            restore()
            
        if re.search('q',option,re.IGNORECASE):
            sys.exit()



#Main
start()            




