Retrospect Insert Tape Issue
By: James Reynolds - Revised: 2014-01-23 richard
Introduction
To be notified by email that Retrospect 5.x or 6.x needs a tape change, you have to enable media request timeout. Media request timeout will cancel a backup.
James will cover how we used Scripting UI with AppleScript to give use the functionality we wanted from Retrospect when it requests a tape. Like repeat the email to remind us periodiaclly (about one hour), not send emails at certain times (like late nights & weekends), and email us when the tape request dialog is taken care of.
What is the issue?
To be notified by email that Retrospect 5.x or 6.x needs a tape change, you have to enable media request timeout. Media request timeout will cancel a backup. So if you are running a backup, and it asks for a new tape, it will email you about it *after* it cancels the backup. So verification does not occur (if you are doing verification), and you have to start the backup over once you put the new tape in.
This might not be such a bad idea in some cases, but not the majority of the time, especially when starting a new backup. For starters, who has the ability to sit in front of the backup server so that they know when a new tape is needed.
What we wanted was Retrospect to email us when it requests a tape, repeat the email to remind us periodically (about one hour), not send emails at certain times (like late nights & weekends), and email us when the tape request dialog is taken care of. Anyone familiar with the network monitoring software
Intermapper knows where we are coming from. Intermapper does all of this.
Workaround
Our solution is to enable UI Scripting on the Macs we run the Retrospect server and use a AppleScript to detect the UI components in the tape request window. If the components are present, then it knows the tape request window is active. If the components are not present, it knows that there is no tape request window active.
So using UI Scripting, we can tell when the tape request window is up, and then the rest of the logic, when to email and such, is handled by the AppleScript.
What is UI Scripting? UI Scripting is a feature new in Mac OS X 10.3 that allows you to control applications through the graphical user interface, whether or not the applications are "AppleScriptable" or not. Any application that uses Apple's API for windows and widgets are scriptable through UI Scripting.
If you want to customize the way our script checks for the UI elements, you will need a tool to inspect the Retrospect UI. Apple provides a tool named
UI Element Inspector. Another tool is
PreFab UI Browser (which is what we use).
Read more about
UI Scripting.
Read how to enable
UI Scripting.
Script
To use the script, you first have to enable UI Scripting (see above link). Then you need to have your Retrospect server autologin (best to put it in a secure room). Add the script to Login's StartupItems (found in System Preferences, Accounts, StartupItems). The script needs to always be running.
Here is the script. Please be aware, we are still testing it to make sure everything works as expected. Consider it Beta software.
Or view it here:
global email_address
global messageSent
global idle_timer
global messageSentResetTime
global messageSentResetCountdown
global email_start_time
global email_end_time
global email_days
on run
-- This is the email address that will get emails (Mail.app must be configured)
set email_address to {"youremailhere@yourschoolhere.edu"}
-- This is how many seconds pass between each check.
set idle_timer to 120 -- seconds
-- This next number is multiped by idle_timer to get the number of seconds that must pass before a second reminder message is sent
set messageSentResetTime to 30 -- multiple this by idle_timer, result is seconds
-- This is the time that emails will start sending
set email_start_time to 9
-- This is the time that emails will stop sending
set email_end_time to 20
-- These are the days that emails send
set email_days to {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}
----------------------------------------
-- Don't change the following
set messageSent to false
set messageSentResetCountdown to messageSentResetTime
end run
on idle
-- Make sure Retrospect is running before doing anything
try
tell application "Finder"
set process_list to name of every process
if process_list does not contain "Retrospect" then
return idle_timer
end if
end tell
on error
return idle_timer
end try
-- Let user know why Retrospect is going to pop in front
try
activate
display dialog "Checking for new tape" giving up after 3
end try
-- Check to see if Tape request window is open
set tapeRequestWindowActive to false
try
with timeout of 8 seconds
activate application "Retrospect"
tell application "System Events"
tell process "Retrospect"
-- search every window for the Tape request buttons
repeat with i from 1 to count of every window
try
get value of button "Stop" of window i -- This will produce an error if the tape request window isn't open
get value of button "Eject" of window i -- This will produce an error if the tape request window isn't open
-- if execution reaches this point, then Retrospect needs attention
set tapeRequestWindowActive to true
end try
end repeat
end tell
end tell
end timeout
on error mes number num
if num is not equal to -1712 then -- -1712 is the Timeout error (I am not 100% sure about that)
try
activate
display dialog "Error: " & mes & " Number: " & num giving up after 30
end try
end if
end try
if tapeRequestWindowActive then
try
say "Backup server needs new tape"
end try
if messageSent is false then
-- Send message
set theSubject to "Retrospect script: attention needed"
set theBody to "Please swap tapes."
try
activate
display dialog "Sending mail: " & theBody giving up after 5
end try
sendMail(theSubject, theBody, email_address)
set messageSent to true
set messageSentResetCountdown to messageSentResetTime
else
-- Count down to send reminder notification
if timeWindow() then
set messageSentResetCountdown to messageSentResetCountdown - 1
if messageSentResetCountdown is less than 0 then
-- Timer has expired, send a reminder message
set messageSent to false
end if
end if
end if
else
if messageSent then
-- Send a message saying everything is now ok
set theSubject to "Retrospect script: I'm happy"
set theBody to "Tapes have been swapped."
try
activate
display dialog "Sending mail: " & theBody giving up after 5
end try
sendMail(theSubject, theBody, email_address)
set messageSent to false
end if
end if
return idle_timer
end idle
on timeWindow()
--check to see if the day and time are ok to send messages
set theDate to current date
set timestr to time string of theDate
set oldTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to {":"}
set theHour to text item 1 of timestr
set AMPM to word 4 of timestr
if theHour is equal to "12" then
set theHour to theHour - 12
end if
if AMPM is equal to "PM" then
set theHour to theHour + 12
end if
set timeCheck to false
if theHour as number is greater than email_start_time then
if theHour as number is less than email_end_time then
set timeCheck to true
end if
end if
set dayCheck to false
set todays_day to weekday of theDate as string
if email_days contains todays_day then
set dayCheck to true
end if
if timeCheck then
if dayCheck then
return true
end if
end if
return false
end timeWindow
on sendMail(theSubject, theBody, email_address)
if email_address is {} or email_address is "" or email_address is {""} or theBody is "" then return
set email_address to email_address as string
try
tell application "Mail"
set theEmail to make new outgoing message with properties {subject:theSubject, content:theBody & return & return}
tell theEmail
make new to recipient at end of to recipients with properties {name:"", address:email_address}
end tell
send theEmail
end tell
on error mes number num
try
activate
display dialog mes giving up after 10
end try
end try
end sendMail