Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Configuring a SoftwareUpdate site for OSX

2011, howto, osx, tip

Whenever you run SoftwareUpdate on your OSX machine, many things happen under the covers. It scans the list of software receipts installed (the files in /Library/Receipts are placed whenever you have a file installed with Installer.app; but the canonical reference is the binary database of those files, stored in /Library/Receipts/db/a.receiptdb, is what's actually consulted. This file is also read by pkgutil and can be repaired with repair_packages; when you do a 'Verify Filesystem' in diskutil, it's basically checking that the entries in the receipts database correspond with the correct file permission(s) that are mentioned in the receipts database.

Apple's software update contacts the main Apple site, http://swscan.apple.com/content/catalogs/index.sucatalog (or the 'others', under http://swscan.apple.com/content/catalogs/others/index-leopard(-snowleopard).merged-1.sucatalog), looking for an 'index software update catalog' or 'sucatalog'. This is, in essence, a giant XML file (in PList format) which contains a list of all the products that are available. Part of the reason software update takes so long is the fact that it is simply a giant file to download all the time, and contains updates going back as far as 2005. In order to speed things up, different update sites have been created for different versions of the OS, as described in knowledge base article HT4069:

10.6
index-leopard-snowleopard.merged-1.sucatalog
10.5
index-leopard-merged-1.sucatalog
10.4
index.sucatalog

Software update will use a global proxy (if one is configured) but it's not possible to set up a proxy to use a specific host instead of the global default. However, you can re-point the update site you use to a local site if you have one; the information is stored in the com.apple.SoftwareUpdate preferences domain. (In prior releases of OSX, it was possible to configure this to use a per-user default; since 10.6, it only consults the system-wide update site.) To change the update to point to a different location, do the following:

sudo defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL http://my.internal.host:8088/index-leopard.merged-1.sucatalog

When SoftwareUpdate next runs, it will hit my.internal.host instead of Apple's servers.

So far so good, but how do we get the server in the first place? Well, Apple's softwareupdate server comes with Server (soon to be part of 10.7) but in the meantime, you can configure a caching proxy to point to the http://swcdn.apple.com domain. For example, using Apache (which is widely installed on OSX machines) you could configure this as:

<VirtualHost *:80>
ServerName update.my.internal.domain

CacheEnable disk /
CacheRoot /var/tmp/swupd-cache
CacheMaxFileSize 100000000

ProxyPass /content/catalogs/ http://swscan.apple.com/content/catalogs/
ProxyPassReverse /content/catalogs/ http://swscan.apple.com/content/catalogs/

ProxyPass /content/downloads/ http://swcdn.apple.com/content/downloads
ProxyPassReverse /content/downloads/ http://swcdn.apple.com/content/downloads
</VirtualHost>

When you hit http://update.my.internal.domain/content/catalogs/, it will transparently cache the result. Similarly, the http://update.my.internal.domain/content/downloads/ will also transparently cache results.

The only problem is that the downloaded catalog won't have your server for the downloads; it will contain FQDNs to bounce to the swcdn.apple.com domain. What you need to do instead of caching the catalog results is to have an external process download the catalog (and place it on a filing system somewhere) and then search-and-replace the http://swcdn.apple.com/content/downloads/ links with your own internal update site links. That way, you can be guaranteed to cache both the catalog and the downloaded files themselves.