MacOS – How to automount sparsebundle for Time Machine backups

macostime-machine

I have a disk drive connected to my router that I'm using for TM backups. What I did is I created a .sparsebundle image using Disk Utility and then copied that image to my disk drive. Then, in Terminal I typed the following:

sudo tmutil setdestination /Volumes/MYCIFSvolume

All works OK, but I have to manually mount the .sparsebundle by double clicking it and then Time Machine recognizes the drive and make backups to it.

Is there any way TM automounts this .sparsebundle when a backup is scheduled?

I'm using OS X 10.9

Many thanks,

Best Answer

These instructions assume you're using a sparsebundle file in 10.9 because you use an encrypted drive. If not, modify accordingly.

First, follow the instructions in the link below to figure out how to use security find-generic-password to grab the password to your encrypted drive out of your Keychain programmatically.

http://blog.joshdick.net/2012/10/14/programmatically_mounting_encrypted_disk_images_in_os_x.html

Then create a file called mounter in your local bin directory ~/bin that contains the following code (replace all paths with your paths, and in the security find-generic-password, use the name of the key in Keychain):

#!/usr/bin/env bash -e

PHYSICAL_DRIVE_PATH="/Volumes/Backup/"
SPARSEBUNDLE_PATH="/Volumes/Backup/TimeMachine.sparsebundle"
SPARSEBUNDLE_MOUNT_PATH="/Volumes/Time Machine/"

# Check existing states
if [ -e "$SPARSEBUNDLE_MOUNT_PATH" ]; then
    echo "Already mounted."
    exit 0    
fi

if [ ! -e "$PHYSICAL_DRIVE_PATH" ]; then
    echo "Physical drive not attached"
    exit 0
fi

if [ ! -e "$SPARSEBUNDLE_PATH" ]; then
    echo "Virtual drive not found on physical drive"
    exit 1
fi

# The mount command uses security find-generic-password
# to get the password from the keychain store
MOUNT_PASSWORD=$(security find-generic-password -w -D "disk image password" -l TimeMachine.sparsebundle)
printf $MOUNT_PASSWORD | hdiutil attach -stdinpass -mountpoint "$SPARSEBUNDLE_MOUNT_PATH" "$SPARSEBUNDLE_PATH"

This is a bit verbose, but means no storing passwords anywhere but keychain. In any case, now we have to get it to run. Create a file in ~/Library/LaunchAgents/ like ~/Library/LaunchAgents/com.martorana.dave.mounter.plist and put the following code in it, replacing, of course, the paths with your own paths:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.martoranas.dave.mounter</string>
    <key>Program</key>
    <string>/Users/dave/bin/mounter</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>60</integer>
    <key>StandardOutPath</key>
    <string>/Users/dave/bin/ldout.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/dave/bin/lderr.log</string>
</dict>
</plist>

We're using launchd instead of cron for a host of reasons, the most important being access to your keychain.

Now load your launch daemon:

launchctl load -w ~/Library/LaunchAgents/com.martoranas.dave.mounter.plist

And that should do it. Now launchd will run your shell script every 60 seconds, and if not mounted and available, will mount your sparsebundle disk image.

Cheers,

Dave