Press "Enter" to skip to content

Software Update Server – using launchd and sed to ensure off-net transfers

Like most hosting companies, I imagine, we have a public side network (10 and 100mbit connections) and a private side network (GigE)
We monitor the public side network switch ports for billing purposes and any local server to server traffic we try to keep on the private side network. Things like backups and database queries and mail routing, etc, etc..

Well, with the Software Update Server in Tiger Server we now have the ability to update a large set of systems using a single downloaded copy of updates. So using the nice little utility Software Update Enabler built by Andrew Wellington, we can point all our Xserves running Tiger Server to our single SUS through the backside network.

However….

The SUS is really just a customized instance of Apache whose content is updated by the swupd_sync process that is periodically run. It connects to the Apple SUS (akamai cache somewhere close) and compares the “index.sucatalog” file, which is merely a big plist xml file to it’s local copy and downloads the missing pieces.

When the swupd_sync process is done it replaces the host name/prefix directory portion of all the URLs that are in that file with it’s own hostname value like so:

<key>English</key>
<string>http://swcdn.apple.com/content/downloads/55/22/022-2725/252QW5yQ2d3BLTgrZn8CVB5KGj7YtyZt3b/022-2725.English.dist</string>
is transformed to:

<key>English</key>
<string>http://server.yoursus.com:8088/022-2725/252QW5yQ2d3BLTgrZn8CVB5KGj7YtyZt3b/022-2725.English.dist</string>

So here’s the problem.

That “server.yoursus.com” host name is more than likely the hostname of the public interface of your server. When a Tiger Xserve connects to our SUS (through it’s backside interface), it will read the index.sucatalog file, but when it goes to download the actual update files, it will be using those urls that swupd_sync generated. Which means the downloads will travel through the public side interfaces and completely negate the purpose of running the Updates through the backside network.

Now, I have asked the OS X Server product manager to allow a preference in the Software Update panel of Server Admin to set the host name that will be used by swpupd_sync in constructing those urls, but that feature hasn’t been added yet, so I had to come up with a workaround of my own to ensure that those urls in the index.sucatalog file refer to a private side network interface.

Enter launchd and sed

First thing to do was to come up with a script that altered those urls. I needed a quick and dirty find and replace on a text file. Not much out there that’s simpler at doing that than sed.

My simple shell script “alterswuphost.sh” for altering index.sucatalog which is in /usr/share/swupd/html
#!/bin/sh –
#

cd /usr/share/swupd/html;
sed -i .bkp ‘/server/s/server\.yoursus\.com/serverINTERNAL\.yoursus\.com/g’ index.sucatalog;
exit 0;

this says: for lines that contain “server”, find instances of “server.yoursus.com” and change them to “serverINTERNAL.yoursus.com”

the switch -i .bkp makes a backup of the file before running the find/replace

Now, I needed some way to know when I should run this script and this is where launchd came in to play.
I created a new LaunchAgent script to run whenever launchd noticed a change to the index.sucatalog file using the WatchPaths parameter:

<?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>info.networkjack.alterswupdhost</string>
<key>ProgramArguments</key>
<array>
<string>/Server/Scripts/alterswuphost.sh</string>
</array>
<key>WatchPaths</key>
<array>
<string>/Library/Logs/SoftwareUpdateServer.log</string>
</array>
<key>OnDemand</key>
<true/>
</dict>
</plist>

which I put into /Library/LaunchAgents/info.networkjack.alterswupdhost

and activated with:

launchctl load /Library/LaunchAgents/info.networkjack.alterswupdhost
so when swupd_sync updates it’s log file, launchd will follow it up with running this script that alters the hostnames with sed.

The Launch Agent watches “/Library/Logs/SoftwareUpdateServer.log” since that’s the most reliable of all the files to watch.

and that’s it!

I have this setup now and it seems to work ok.

4 Comments

  1. sanderw
    sanderw January 9, 2007

    Not 100% sure I understand what you’re wanting to do, but couldn’t you just update your /etc/hosts entry (/private/etc/hosts on the Mac, I think) to point to a different IP for swcdn.apple.com?

    I guess it depends on if you’d ever want to go to the original address.

  2. Brian Blood
    Brian Blood January 9, 2007

    My primary purpose is to not pollute our traffic graphs and billing scripts with traffic that is merely running from one server to another as it’s not traffic that we have to ultimately pay for and bill the client for.

    Secondary purpose is to be able to download the updates over a much faster network as most of our client’s colo boxen are only connected via a 10 mbit link whereas the backside is on GigE.

    As for your hosts file change, I’d rather not override host names published by other entities.

    Having a deterministic way of forcing data traffic to the backside gige network by using slightly altering the existing processes has a much smaller footprint.

  3. sanderw
    sanderw January 10, 2007

    It’s a little more complex, but this might also be a good candidate for a proxy server. That way you’d have a single place to administer any other hostname swaps you might want/need to do.

  4. Brian Blood
    Brian Blood January 10, 2007

    unfortunately, that would have a far more reaching effect (and possible unintended consequences) than the specific instance I need to remedy here.

Leave a Reply