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

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

$
0
0

Relevant specs:

- Mac OS 10.8.3

- Fusion 4.1.4

 

Virtual machines:

- Windows XP Pro imported from Boot Camp

- Windows 7 Boot Camp

 

VMware recommends that virtual machines (VMs) not be backed up using Apple's TimeMachine, unless snapshots are used. However, many advanced, experienced users strongly discourage that snapshots be used, as each snapshot chains on the prior one, meaning that the failure of any link can cause your VM to fail, as well as increasing the complexity of your VM and reducing its performance.

 

So, I'm trying to write an AppleScript that powers down any VMs running, then copies a backup. That should be clean and simple.

 

However, I've run into some problems with a suspended VM (so Boot Camp VMs aren't a problem since they can't suspend). If a VM is suspended, then you need it to be powered off (shut down) in order to back it up cleanly. The only way to power off a suspended VM is to first resume it, then power it off. That's not a problem for AppleScript if the VM is open in its own window. VMWare Fusion correctly reports this VM as suspended, allowing the script to first resume it, then shut it down.

 

Unfortunately, if the VM window has been closed so that it doesn't have its own window, but rather only appears in the Virtual Machine Library, then VMware Fusion does not correctly report the VM as suspended. Even if the VM is suspended, VMware Fusion reports that state as "powered off", meaning that a suspended VM would be backed up.

 

I've tried to "resume" all of the VMs, but this actually starts any VMs that are "powered off" (shut down), which, obviously is a disaster (how long do I wait for multiple VMs to start up simultaneously before it's safe to force them to shut down?).

 

I've tried to open the VM's window, but if the VM windows are closed, then AppleScript only sees two windows: "Virtual Machine Library" and "Updates". The AppleScript "Virtual Machine Library" window object doesn't appear to have any ability to access the individual VM windows (even though I can right-click on a VM in the "Virtual Machine Library" and choose "Show Windows" in order to open up the VM window and get it into the state that I need. Also, the AppleScript window is able to reference / access the VM "document" (or AppleScript object / VM), but the VM "document" (which I'm able to access) isn't able to reference / access its own window. (So, the window contains the document, allowing the window to access the document, but the document inside the window has no ability to reference the window which contains it.)

 

At this point, I'm looking at setting VMWare Fusion "Preferences…" -> "General" -> "When closing a virtual machine:" to "Power off the virtual machine". As long as users don't specifically choose to suspend a VM, then their VMs are automatically shut down ("powered off"). Meaning, I'm left with crossing my fingers that no users change this setting, nor suspend their VMs.

 

Does any one have any ideas?

 

Am I having this problem because the specific VM that I'm testing is imported? (Would a normally created VM not incorrectly report its state when it doesn't have a window?)

 

Is this fixed in VMware Fusion 5? (We would probably upgrade if that's the case.)

 

Also, if anyone reports this bug to VMware, then please note that in a response below. Otherwise, I'll report it (assuming that no one shows to me that it isn't actually a bug).

 

And, for anyone who'd like to help with the code, what I have so far is found below with some test values commenting out production values. You'll want to save it as an application, then run it like any normal application.

 

Thanks, in advance!

 

 

<code>

(*

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

 

 

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 --21 -- 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 : 40 --(4 * 60) -- in seconds

 

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

 

--TODO: test to see if backup has been done today

 

-- 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

try

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 aObj indocuments

set powerState to power state of aObj

if powerState is powered on then

power off aObj with force -- doesn't work on suspended VMs

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

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

delay resumeDelay -- give VM time to resume; usually takes < 30s, but if multiple VM running, then can be ~2min

power off aObj with force

endif

endrepeat

quit

endtell

onerror errMsg number errNum

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

endtry

 

-- back up VMs

 

exitrepeat

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

display dialog "Backup has been delayed until later."

exitrepeat

endif

endrepeat

endif

return idletime

endif

endtell

endidle

 

</code>


Viewing all articles
Browse latest Browse all 38932

Trending Articles