3

Years ago I put together the following expect script to perform Open Directory backups under Tiger Server and it's worked well under Leopard Server as well:

#!/usr/bin/expect -f

set date [timestamp -format "%Y-%m-%d"]
set archive_path "path/to/you/backup/dir"
set archive_password "password"
set archive_name "opendirectory_backup"

spawn /usr/sbin/slapconfig -backupdb $archive_path/$archive_name-$date
expect "Enter archive password"
send "$archive_password\r"
expect eof

It's one of the few scripts that still lives in root's crontab as opposed to having a launchd plist. It's rwx by root only for obvious security reasons.

Now, the problem is I upgraded my Open Directory Master to Mac OS X 10.6.4 Snow Leopard Server a couple weeks ago and it hasn't worked since... when run by cron. If I log in as the root user and run it manually it works correctly and creates the resulting encrypted disk image. When run by cron, it goes through the full motions (incl. output in /Library/Logs/slapconfig.log that matches that of when it's run manually), but the disk image file is never created. However, in `/var/log/system.log/ I see the following output:

Jul 23 03:00:08 servername hdiejectd[93114]: running
Jul 23 03:00:11 servername diskimages-helper[93111]: -frameworkCallbackWithDictionary: threw exception calling home.
Jul 23 03:00:11 servername diskimages-helper[93111]: threw exception reporting results back to framework.
Jul 23 03:00:21 servername hdiejectd[93114]: quitCheck: calling exit(0)

When run manually, that output is as follows (no diskimages-helper exceptions):

Jul 23 14:29:27 servername hdiejectd[7776]: running
Jul 23 14:29:40 servername hdiejectd[7776]: quitCheck: calling exit(0)

In both cases there is no user logged in via the GUI. I have a couple friends who're running the same script on their OD Masters and it also no longer runs via cron since upgrading to Snow Leopard Server.

I recall some issues with Mac OS X's command line disk image tools that required keychain access, but I don't recall the specifics. Did something related to that get more strict in Snow Leopard Server?

Any ideas or suggestions?

morgant
  • 1,470
  • 6
  • 23
  • 33
  • I'm always wary of relative directory specs in jobs run by `cron`. Surely it couldn't be as simple as changing `set archive_path` to an absolute directory, could it? – Dennis Williamson Jul 23 '10 at 21:27
  • All paths are absolute. That was just a slip up in my obfuscation that `archive_path` doesn't have a leading slash. – morgant Jul 26 '10 at 15:09
  • As a slightly off-topic comment cron has been deprecated on Mac OS X in favour of launchd since Mac OS X 10.4. It might be worth considering making the move. – Cromulent Aug 27 '10 at 12:44
  • I'm well aware and, as mentioned above, this is one of the only scripts that's _not_ a `launchd` job. While `cron` has been deprecated for a few major releases of Mac OS X now, it is still fully supported. That said, I'll try a `launchd` job for this to see if there's any difference in functionality. – morgant Aug 30 '10 at 01:55

2 Answers2

4

I experienced the same problem debugged the original script, for me the default expect timeout of 10 seconds was causing the embedded hdiutil command to be aborted. I fixed this by adding:

set timeout 120

In the expect script. Now the script is working fine again. My script:

#!/usr/bin/expect -f

set date [timestamp -format "%Y-%m-%d"]
set archive_path "path/to/you/backup/dir"
set archive_password "password"
set archive_name "opendirectory_backup"
set timeout 120

spawn /usr/sbin/slapconfig -backupdb $archive_path/$archive_name-$date
expect "Enter archive password"
send "$archive_password\r"
expect eof
Omniver
  • 41
  • 2
0

Okay, I now have a working solution. I started by writing a new bash script (as opposed to using expect) which wrapped around Apple's serveradmin utility (itself being a wrapper around the slapconfig -backupdb I had been calling directly from the expect script):

#!/bin/bash

dst="/path/to/your/backup/directory"
pass="password"

host=$(hostname)
date=$(date +%Y-%m-%d-%H%M)

serveradmin command <<-EOC
    dirserv:backupArchiveParams:archivePassword = $pass
    dirserv:backupArchiveParams:archivePath = ${dst}/od_backup-${host}-${date}
    dirserv:command = backupArchive

EOC

It's based on this script, but uses bash "here document" instead of creating a file on disc containing the serveradmin commands (incl. plaintext password) to be run.

This one worked fine when run from the command line as well, but still no .sparseimage was created when it was run from cron. So, the second stage of my fix was, as I mentioned above in the comments on my original question, to create a launchd plist to run it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>tld.domain.od_backup</string>
        <key>ProgramArguments</key>
        <array>
            <string>/var/root/sbin/od_backup</string>
        </array>
        <key>StartCalendarInterval</key>
        <dict>
            <key>Hour</key>
            <integer>2</integer>
            <key>Minute</key>
            <integer>30</integer>
        </dict>
    </dict>
</plist>

Naturally, I loaded the plist w/sudo launchctl load /Library/LaunchDaemons/tld.domain.od_backup.plist (domain & tld changed to protect identity). And, it seems to run correctly when called by launchd. The original script might've also run correctly if called by launchd, but I haven't tested it.

morgant
  • 1,470
  • 6
  • 23
  • 33