Launchd – Run command on DHCP IP address change

Every once and a while I need to run a command when a clients IP address change.  In OS X it is really easy to do with launchd.  All you need to do is set a watch path for the DHCP leases folder “/private/var/db/dhcpclient/leases/”.  See the example below:

<?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.example</string>
 <key>UserName</key>
 <string>root</string>
 <key>ProgramArguments</key>
 <array>
 <string>PATH TO COMMAND THAT YOU WANT TO RUN</string>
 </array>
 <key>WatchPaths</key>
 <array>
 <string>/private/var/db/dhcpclient/leases/</string>
 </array>
</dict>
</plist>

You will want to replace the “Label” string with your own (typically in reverse domain notation ) and the “ProgramArguments” string with the path and options for the command/program you want to run.

Imaging computer systems with PHP and Expect

The History:

In my environment I have a lot of Macs.  The default option these days for imaging Macs is Deploy Studio.  When I first looked at Deploy Studio it seemed interesting but didn’t quite fit with my environment which has a fair amount of wireless systems so I couldn’t NetBoot them which is the preferred method to restore a computer using Deploy Studio.

Before Deploy Studio came out I had developed my own system imaging process that worked well enough.  I created a local maintenance partition on every computer that would restore the primary partition that had a simple Bash script to restore the computer with the latest image..  It would automatically select the correct image for the computer running the script and then restore the primary partition then restart to the freshly imaged drive.  Never had many problems with it, so I never was forced to adapt my environment to Deploy Studio (if you have to adapt a problem to a solution, you have the wrong solution).  The only downside to my script based restore process was that anytime I needed to update the script I had to deploy it to every maintenance partition.  Which can be automated, but I knew I could do better.  Developing something better has been on my list of things to do for a while now.

The Problem:

What I needed was something that would be server based and scalable.  I basically wanted an easy way to connect to the server, have it use the latest version of the restore script, determine the correct image, restore the computer and reboot.  Same as before but better.  It also needed to be as simple as possible and have the ability to scale to serve multiple gigs of data at a time.  I also wanted it to have some sort of GUI so that anyone performing a restore could get some quick feedback on progress or diagnose any issues.

The Solution:

I initially thought I was going to write some sort of thin client that I would deploy to the management partition.  Fortunately, a web browser makes a great thin client so I was able to skip that step.  What I ended up with is a web application that connects to the client via SSH and performs all of the required steps to restore the primary partition and restart the computer.  Now I have a quick and easy way to restore any computer and since its a web application I can scale it like I would scale any web application.

The Video:

 

The Details:

When I was debating what language to use for this I was torn between Ruby, Python and PHP.  At the end of the day I went with PHP because of the PHP-Expect extension.  It makes it fairly trivial to have PHP send Expect commands to a client and read results that can then be processed.  To get the progress on the restore process I used Comet (aka long polling).  The restore command itself is Apple’s built in ASR command, with the images hosted on a load balanced web server.  I’ll post more information on PHP-Expect and Comet in a bit but wanted to share this now.