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.

Retrospect tape request window

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.

Download script. – ZIP-File, 26.7 KB

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