We’ve covered using launchd in the past for things like detecting when external drives are plugged in to initiate a backup. In this simple tutorial, we’ll demonstrate how to backup the core service settings of your Mac OS X Server (AFP, SMB, Xgrid etc…) and also how to back up your Open Directory database. The core of the procedure has been taken from a script Mike Bombich posted on his site.

Getting Started

The backup procedure uses two scripts. The main script (OD_backup.com) is the one that does the actual work of backing up your server and creating the plist and OD sparseimage files. The second script is used by launch services (launchd) to run the backup script at a specified time (org.macresearch.od-backup.plist).

Obviously you need to be an administrator on your server and have access to the root account (serveradmin must be run as root, or via sudo). Since this is going to be run automatically, all paths, files and output will be owned by the root user and the service will be installed at the system level by root.

Backup Script

Here is the full listing for the script:


#!/bin/bash

# Path to the root folder where the backups will be stored
# This path should not be on the root volume, and not accessible
# to non-administrators

recover_path="/path/to/backup"

# You can either backup all of the services (even those not in use)
# or you can specify which services you want to backup.

services=`serveradmin list`
#services="afp ipfilter smb"

# This is the password you will use to recover your OD sparseimage.
# It should NOT be the same as your Directory Administrator password
# for security reasons.

passwd="cr38aNuPassWd"

###############################################################
#### Advanced modification only. The rest can be left as is ###
###############################################################

# This is the hostname of the server the script is running on
# This variable is used so that the same script can be run
# from multiple servers on a single share point
server=`hostname`

# Get today's date and format it as YYYYMMDD
date=`date ''+%c%m%d'' | awk '{printf $5}'`

# Set the full path to where this days backups will be stored
recover=${recover_path}/$server/$date

mkdir -p $recover
chmod 600 $recover

# grab the server configuration plists
for service in $services; do
    serveradmin -x settings $service > $recover/$service.plist
    sleep 1
done

# Backup Open Directory
od_backup=$recover/od_backup
ts=`date ''+%F''`
echo "dirserv:backupArchiveParams:archivePassword = $passwd" > $od_backup
echo "dirserv:backupArchiveParams:archivePath = $recover/od_$ts" >> $od_backup
echo "dirserv:command = backupArchive" >> $od_backup
echo "" >> $od_backup

serveradmin command < $od_backup

exit 0

In order for this to run you’ll need to be sure to make the script file executable. Starting from the top:


recover_path="/path/to/backup"

This is the location where you want the base folder structure to be placed. It’s important this folder be accessible by the “root” user (which is important to remember if you place the folder on a networked share). And you want to be pretty restrictive in who access to the folder.


services=`serveradmin list`
#services="afp ipfilter smb"

This section deals with what services on the server you wish to backup. There are two approaches to backing up the server. If you don’t have a lot of other administrators on the system turning services on and off. Comment out the first line and comment out (or delete) the second.

If you don’t want to have to remember to add a service to the list whenever you enable a service on your server, you can leave the settings as they are for now. The method simply gets a list of all of the serveradmin services on the system. You will generate more plist files, which in turn take up more space, but you are guaranteed to not forget a service later should you enable it.


passwd="cr38aNuPassWd"

VERY IMPORTANT… You need to create a password that will be used later when creating the Open Directory backup archive. This password is useful in the event that someone who isn’t authorized on to access the OD information somehow gets a hold of the archive file (that is, they can’t simply unarchive it, restore it and then have access to your entire OD database). For security reasons this password should not be the same as a directory administrators password, since it is stored in the clear in the this file (of course you’ll want to set the permissions on this file to be readable by root only, but still).

The rest of the script file shouldn’t really need to be modified, but we’ll go through it for completeness.


server=`hostname`

date=`date ''+%c%m%d'' | awk '{printf $5}'`

recover=${recover_path}/$server/$date

mkdir -p $recover
chmod 600 $recover

The script can be stored in a central location and run on multiple servers from a shared drive. So to keep the relevant directory information organized we first get the name of the server. Then we construct a path using the backup path, server name and the current date. Finally we create the directory path and change permissions so that only the owner (again this is going to be run as root) can access the folder.


for service in $services; do
    serveradmin -x settings $service > $recover/$service.plist
    sleep 1
done

Simple stuff… we just loop through our service list and create plists for each service that get stored at the recovery location.


od_backup=$recover/od_backup
ts=`date ''+%F''`
echo "dirserv:backupArchiveParams:archivePassword = $passwd" > $od_backup
echo "dirserv:backupArchiveParams:archivePath = $recover/od_$ts" >> $od_backup
echo "dirserv:command = backupArchive" >> $od_backup
echo "" >> $od_backup

serveradmin command < $od_backup

This is the part that backs up your open directory information. If this script runs on a system that is an OD replica or a stand alone server, this portion of the process will essentially be skipped, since only OD masters actually respond to the above commands.

Note that if your run this script manually on the command line (again as root or via sudo) on your OD master you’ll get an error message that something didn’t work. The exact error is: dirserv:error = “backupArchive error”. I’m not certain what this error is, and a Google search turned up a thread stating that it’s harmless.

Remember this script file needs to be made executable and accessible by root.

Launchd

This part is easy. The complete listing of the plist file is below:


<?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>org.macreserch.od-backup</string>
	<key>ProgramArguments</key>
	<array>
		<string>/path/to/backup/scripts/OD_backup.com</string>
	</array>
	<key>LowPriorityIO</key>
	<true/>
	<key>Nice</key>
	<integer>1</integer>
	<key>StartCalendarInterval</key>
	<dict>
		<key>Hour</key>
		<integer>16</integer>
		<key>Minute</key>
		<integer>43</integer>
	</dict>
</dict>
</plist>

You need to modify the array string line pointing to the path where your OD_backup.com script is:


/path/to/backup/scripts/OD_backup.com

Then below you can modify the time you want the script to be run. The current time is set to 4:43pm. Why? No particular reason.

Installing

Ok… Now is the time to copy your files to their appropriate locations. The OD_backup.com script is placed in the location you specified in the plist file. Again, make sure root can access this location (in the case of network mounts… NFS maproot=nobody I’m looking at you). Then copy the plist file to the following location:

sudo cp org.macresearch.od-backup.plist /System/Library/LaunchDaemons

Then tell launchd about it:

sudo launchctl load /System/Library/LaunchDaemons/org.macresearch.od-backup.plist
sudo launchctl list


...
org.xinetd.xinetd
com.openssh.sshd
org.macresearch.od-backup

Then at your specified time the script should run and the directory contents filled with your settings files and OD database backup.

To restore a setting, go to the date that you want to restore from and copy the plist file to the Desktop (make sure to copy it as root, but to change the permissions so that the Desktop user can access it). Then open Server Admin, click on the specific service you wish to restore on that server and then drag and drop the plist file over the settings portion of the Server Admin GUI.

To restore your OD database, go to Server Admin, Open Directory, and then select the “Archive” tab. There you can select to restore from your sparse image. You’ll be prompted for a password, and this is the password you used for in your script. Not the OD administrators password.

Note that you can create plist files and OD archives manually. For plist files, when you click on a service then the settings tab, a little icon appears in the lower right hand corner of the Server Admin GUI. Clicking that will save the settings to a plist file. For Open Directory, the same location where you restore your database, you can also archive it.

The full scripts can be downloaded below.