Quantcast
Channel: VMware Communities: Message List - VMware Fusion® (for Mac)
Viewing all articles
Browse latest Browse all 38932

Re: Trying to write AppleScript to power down VMs, then back them up; VMs not reporting suspended state correctly

$
0
0

Below is what appears to be a working script.

 

This is my first time writing any substantial amount of Applescript, so any feedback would be extremely welcome. You'll notice that I had to "kludge" some things (like, I couldn't figure out how to get both the backup location and VMs location to both be POSIX references).

 

No one has challenged nor stated that they've submitted the bug that I seem to have found regarding VMware's failure to correctly report suspended VMs as suspended if the VM has no windows open, so I'll go ahead and submit that.

 

Again, I would love code improvements!

 

Thanks!

 

-----

 

(*

Applescript application to auto back up virtual machines after certain period of system idle

 

Requirements:

[ ] "Power off the virtual machine" must be selected in VMWare Fusion "Preferences…" -> "General" -> "When closing a virtual machine:" -- this is needed because if a VM window is closed, then VMware reports the power state of a VM as "powered off" even if the VM is actually "suspended"; and from a document object there is no way to access its window

[ ] In "System Preferences…" -> "Energy Saver" -> "Power adapter" -> "Computer sleep" must be set to a greater value than backup_after + ( check_every * 2 )

 

 

http://culturedcode.com/forums/read.php?7,30174,30597

 

To make this runable, save as application.

To not show in Dock, set LSBackgroundOnly in Info.plist of created app bundle, or other ways in

http://groups.google.com/group/macenterprise/browse_thread/thread/be7db35451e1dc70

*)

 

property afterHours : 8 --23 -- hour of the day to start monitoring idle

property workDayStarts : 5 -- hour of the day to stop monitoring idle

property backupDuration : 2 -- number of hours needed to back up virtual machines

 

global backup_after, check_every -- TODO: do these really need to be global ?

 

set backup_after to 10 --(40 * 60) -- in seconds

set check_every to 5 --(10 * 60)

 

property cancelTimer : 60 -- how many seconds the user has to cancel backup

 

property virtualizationApp : "VMware Fusion" -- variable can't be used in 'tell application' statements or won't compile, so search & replace other instances of "VMware Fusion"

property resumeDelay : 120 --(4 * 60) -- in seconds; usually takes < 30s, but if multiple VM running, then can be ~2min

property powerOffDelay : 60 -- in seconds (Win 7 waits about 40 seconds before forcing unsaved docs to close)

 

property backupLocation : "/Users/mikeong/Documents/Backups/Fusion VMs"

property numBackupsToKeep : 7

 

--property virtualMachinesLocation : "/Users/mikeong/Documents/Virtual Machines"

property virtualMachinesLocation : "Macintosh HD:Users:mikeong:Documents:Virtual Machines"

 

onreopen

display dialog "After " & (backup_after / 60) & " minutes of system inactivity this AppleScript powers down any running virtual machines and backs them up. A check for inactivity is performed every " & (check_every / 60) & " minutes."

endreopen

 

onidle

tellapplication "System Events"

 

-- verify that are in allowed timeframe for backups

set currentHour to (time of (current date)) div hours

if currentHour isless than (workDayStarts - backupDuration) or currentHour isgreater than afterHours then

 

-- check that user has been idle / inactive for sufficient time

set idletime todo shell script "echo $((`ioreg -c IOHIDSystem | sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))"

if (idletime asinteger) > backup_after then

 

-- test to see if backup has been done today

ifmy hasNotBackedUpToday(backupLocation) then

 

-- warn the user that VM application will force close VMs

repeatwith secondsLeft from cancelTimer to 1 by -1

set dialogResult todisplay alert virtualizationApp & " is about to force quit and back up virtual machines " message "This AppleScript is set to force close " & virtualizationApp & ", if it's open, and its virtual machines, and then to back up the virtual machines." & return & return & "Click \"Cancel\" to delay these actions until later, or press \"OK\" to quit and back up." & return & return & secondsLeft & " seconds left." buttons {"OK", "Cancel"} default button "OK" as warning giving up after 1

if secondsLeft = 1 or (button returned of dialogResult) is "OK" then

 

-- force VMs to power off, quit VM app

my powerOffVMsQuitFusion()

 

-- back up VMs

ifmy backupVMs(backupLocation, virtualMachinesLocation) then

display dialog "Successfully backed up virtual machines."

else

display dialog "Failed to back up virtual machines."

endif

 

exitrepeat

elseif (button returned of dialogResult) is "Cancel" then

display dialog "Backup has been delayed until later."

exitrepeat

endif

endrepeat

else

return (8 * 60 * 60) -- have backed up today, so try again in 8 hrs

endif

endif

 

return check_every

 

endif

endtell

endidle

 

 

(*

* Check to see if have backed up in last 16 hrs

*)

on hasNotBackedUpToday(theLocation)

tellapplication "Finder"

set bLocation toPOSIX file theLocation asalias

sort (getfoldersof bLocation) by creation date

set myResult to result

set myResultCount tocountof myResult

 

-- this raises an error if the folder doesn't contain any files

if (myResultCount is notequal to 0) then

set theFile to (item 1 of myResult)

if creation date of theFile isgreater than ((current date) - (16 * 60 * 60)) then

display dialog "Have backed up today."

return false

endif

endif

 

-- delete a backup if have reached max

if myResultCount ≥ numBackupsToKeep then

deleteitem myResultCount of myResult

endif

 

set currDate tocurrent date

set folderName to ("" & (year of currDate) & "-" & (monthof currDate) & "-" & (day of currDate))

make new folder at bLocation with properties {name:folderName}

 

return true

endtell

end hasNotBackedUpToday

 

 

(*

* force VMs to power off, quit VM app

*)

on powerOffVMsQuitFusion()

tellapplication "VMware Fusion"

activate -- can't test to see if a VM is suspended unless VMware is running

delay 10 -- give the application time to open

 

repeatwith currVM indocuments

set powerState to power state of currVM

 

-- power off doesn't work on suspended VMs

if powerState is suspended then -- VM reports powered off even when actually suspended, reports correctly if VM's own window open (VM Library, right-click on VM, then select "Show Windows")

--display dialog "VM " & (name of currVM) & " is suspended"

resume currVM -- only want to resume if actually suspended, otherwise it starts powered off VMs

delay resumeDelay -- give VM time to resume

endif

 

if powerState is powered on then

--display dialog "Name: " & (name of currVM)

--display dialog "Name: " & (OS name of currVM)

 

-- XP unsaved docs prevent power off unless with force, Win7 works without force

try

(*if (OS name of currVM) contains "7" then

--display dialog "Win 7: would power off withOUT force"

power off currVM

delay powerOffDelay

else*)

--display dialog "Not Win 7 (XP, etc.): would power off with force"

power off currVM with force

--end if

onerror errMsg number errNum

tellapplication "Finder"

display dialog ("errMsg: " & errMsg & ", errNum: " & errNum)

endtell

endtry

 

endif

endrepeat

 

quit

delay 5

 

endtell

end powerOffVMsQuitFusion

 

 

(*

* Back up VMs, deleting oldest backup if necessary

*)

on backupVMs(thisLocation, thisVMsLocation)

tellapplication "Finder"

set thisBackupLocation toPOSIX file thisLocation asalias

sort (getfoldersof thisBackupLocation) by creation date

set myFinderResult to result

 

-- This raises an error if the folder doesn't contain any files

if ((countof myFinderResult) = 0) then

display dialog "Error. What happened to the folder that was just created?"

return false

else

set backupFolder to (item 1 of myFinderResult)

--display dialog "Folder name: " & (name of backupFolder)

 

-- check to see if folder is empty

if ((countfilesof backupFolder) is notequal to 0) then

display dialog "Error. Backup folder wasn't empty."

return false

endif

 

-- copy virtual machines to backup folder

--set vmsLocation to alias "Macintosh HD:Users:mikeong:Documents:Virtual Machines"

set vmsLocation toalias thisVMsLocation

duplicateeveryfileof vmsLocation to backupFolder

 

return true

endif

endtell

end backupVMs


Viewing all articles
Browse latest Browse all 38932

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>