Mac OS X Server,  Mass Deployment

Using the Caching Service Command Line Interface

The Caching Server in OS X Server 5 is pretty simple, right? You open up the server app and then click on the On button and you’re… off… to… the… races… Yup. There are also a few options that you can configure using the Server app. You can configure which IP addresses (or networks) are able to access your server. You can configure where the cache is stored. You can configure the amount of Cached used. And you can clear out that cache. Boom. Including the ON button, you’ve only got 5 things you can do here. Pretty easy.

To script kicking off the service as just a proxy that caches all patches that it can, simply use the following command:

sudo serveradmin start caching

The above command simply enables the service and starts the daemon. At that point, it registers with Apple and starts caching what it can. For many environments, this is pretty much all you need to do.

But you can also configure the options available in the GUI, and a few that aren’t, using the command line. And then there are some pretty cool things you can do in Caching under the hood that aren’t included in the Server app. Let’s look at what it might take to script setting up the Caching service. For example, if we wanted to do scripted Caching Server deployments. Well, we’d need to start the service. By default the service would start with only local subnets being able to access the service and all available content would be heated. Additionally, the default location for the cache is /Library/Server, with no limit to the cache and a reserved volume space of 25000000000 bytes. You can see this by looking at the output of serveradmin with a settings verb and the caching service, as follows:

sudo serveradmin settings caching

Which results in the following:

caching:ServerRoot = "/Library/Server"
caching:ReservedVolumeSpace = 25000000000
caching:LocalSubnetsOnly = yes
caching:Port = 0
caching:CacheLimit = 0
caching:DataPath = "/Library/Server/Caching/Data"

Now, let’s open up the caching server to the world, assuming of course that people can’t get to it unless they’re routable on our network. This makes caching for multiple subnets in a given LAN environment much simpler. To do so, we’d feed that caching:localSubnetsOnly back in, with a no:

sudo serveradmin settings caching:LocalSubnetsOnly = no

Once the service is started, you will be able to perform tasks, such as disabling the iCloud caching option. This is done by setting the AllowPersonalCaching key to false, as follows in the /Library/Server/Caching/Config/config.plist.

<key>AllowPersonalCaching</key>
<integer>false</integer>

This can be done using the serveradmin command as well, using the settings verb with the caching service and the AllowPersonalCaching key, as follows:

sudo serveradmin settings caching:AllowPersonalCaching = no

You can also limit the space that the Caching Server uses for cached iCloud data with the Settings verb, the caching service and the PersonalCacheLimit keep, provided the PersonalCacheLimit doesn’t exceed the CacheLimit. For example:

<key>PersonalCacheLimit</key>
<integer>200000000000</integer>

In /Library/Server/Caching/Config/ you’ll find a file called Config.plist. Here, you’ll find way more settings, including those not output when you run serveradmin. You can actually drop lots of settings into new servers by copying this file into the correct location. However, prior to doing so, you’ll need to sanitize the file. There are two unique keys that should never be copied between servers. The first is the ServerGUID. The ServerGUID is a generated unique identifier that the server creates for itself when started.

<?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>CacheLimit</key>
<integer>0</integer>
<key>DataPath</key>
<string>/Library/Server/Caching/Data</string>
<key>LastConfigData</key>
<data>
XXX
</data>
<key>LastConfigURL</key>
<string>http://suconfig.apple.com/resource/registration/v1/config.plist</string>
<key>LastPort</key>
<integer>52303</integer>
<key>LocalSubnetsOnly</key>
<true/>
<key>Port</key>
<integer>0</integer>
<key>ReservedVolumeSpace</key>
<integer>25000000000</integer>
<key>SavedCacheDetails</key>
<dict/>
<key>SavedCacheDetailsOrder</key>
<array>
<string>Mac Software</string>
<string>iOS Software</string>
<string>iCloud</string>
<string>Books</string>
<string>iTunes U</string>
<string>Movies</string>
<string>Music</string>
<string>Other</string>
</array>
<key>SavedCacheDetailsStrings</key>
<dict>
<key>de</key>
<dict>
<key>Books</key>
<string>Bücher</string>
<key>Mac Software</key>
<string>Mac-Software</string>
<key>Movies</key>
<string>Filme</string>
<key>Music</key>
<string>Musik</string>
<key>Other</key>
<string>Anderes</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS-Software</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>en</key>
<dict>
<key>Books</key>
<string>Books</string>
<key>Mac Software</key>
<string>Mac Software</string>
<key>Movies</key>
<string>Movies</string>
<key>Music</key>
<string>Music</string>
<key>Other</key>
<string>Other</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS Software</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>es</key>
<dict>
<key>Books</key>
<string>Libros</string>
<key>Mac Software</key>
<string>Software Mac</string>
<key>Movies</key>
<string>Películas</string>
<key>Music</key>
<string>Música</string>
<key>Other</key>
<string>Otros</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>Software iOS</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>fr</key>
<dict>
<key>Books</key>
<string>Livres</string>
<key>Mac Software</key>
<string>Logiciels Mac</string>
<key>Movies</key>
<string>Films</string>
<key>Music</key>
<string>Musique</string>
<key>Other</key>
<string>Autres</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>Logiciels iOS</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>it</key>
<dict>
<key>Books</key>
<string>Libri</string>
<key>Mac Software</key>
<string>Software Mac</string>
<key>Movies</key>
<string>Film</string>
<key>Music</key>
<string>Musica</string>
<key>Other</key>
<string>Altro</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>Software iOS</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>ja</key>
<dict>
<key>Books</key>
<string>ブック</string>
<key>Mac Software</key>
<string>Mac ソフトウェア</string>
<key>Movies</key>
<string>ムービー</string>
<key>Music</key>
<string>ミュージック</string>
<key>Other</key>
<string>その他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS ソフトウェア</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>ko</key>
<dict>
<key>Books</key>
<string>책</string>
<key>Mac Software</key>
<string>Mac 소프트웨어</string>
<key>Movies</key>
<string>동영상</string>
<key>Music</key>
<string>음악</string>
<key>Other</key>
<string>기타</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 소프트웨어</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>nl</key>
<dict>
<key>Books</key>
<string>Boeken</string>
<key>Mac Software</key>
<string>Mac-software</string>
<key>Movies</key>
<string>Films</string>
<key>Music</key>
<string>Muziek</string>
<key>Other</key>
<string>Overig</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS-software</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh-CN</key>
<dict>
<key>Books</key>
<string>图书</string>
<key>Mac Software</key>
<string>Mac 软件</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音乐</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 软件</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh-Hans</key>
<dict>
<key>Books</key>
<string>图书</string>
<key>Mac Software</key>
<string>Mac 软件</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音乐</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 软件</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh-Hant</key>
<dict>
<key>Books</key>
<string>書籍</string>
<key>Mac Software</key>
<string>Mac 軟體</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音樂</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 軟體</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh-TW</key>
<dict>
<key>Books</key>
<string>書籍</string>
<key>Mac Software</key>
<string>Mac 軟體</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音樂</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 軟體</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh_CN</key>
<dict>
<key>Books</key>
<string>图书</string>
<key>Mac Software</key>
<string>Mac 软件</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音乐</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 软件</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
<key>zh_TW</key>
<dict>
<key>Books</key>
<string>書籍</string>
<key>Mac Software</key>
<string>Mac 軟體</string>
<key>Movies</key>
<string>影片</string>
<key>Music</key>
<string>音樂</string>
<key>Other</key>
<string>其他</string>
<key>iCloud</key>
<string>iCloud</string>
<key>iOS Software</key>
<string>iOS 軟體</string>
<key>iTunes U</key>
<string>iTunes U</string>
</dict>
</dict>
<key>SavedCacheSize</key>
<integer>0</integer>
<key>ServerGUID</key>
<string>A955E484-E2A6-4759-A8F4-108CF9B733A7</string>
<key>ServerRoot</key>
<string>/Library/Server</string>
<key>Version</key>
<integer>1</integer>

There’s always some sanity checking you can do. The main reason I’ve seen the server not want to start is because the server cannot register with Apple. The first thing that the server does when it registers is establishes a connection to Apple using the ServerGUID and then pulls down more settings from http://suconfig.apple.com/resource/registration/v1/config.plist and if needed, begins heating the cache. Now, if the serveradmin command reports back a fullstatus that the server is pending and never makes a connection, there are two issues I’ve seen occur. The first is that you copied the ServerGUID from another host that’s already registered with Apple. The second is an error for “The operation couldn’t be completed” with an error code of 1. To see this, you can run serveradmin with fullstatus and then the service identifier and the caching:startupStatus identifier:

caching:RegistrationStatus:error = <62706c69 73743030 d4010203 04050618 19582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0a4 07081112 55246e75 6c6cd409 0a0b0c0d 0e0f1056 4e53436f 64655a4e 53557365 72496e66 6f584e53 446f6d61 696e5624 636c6173 73100180 00800280 035f1014 636f6d2e 6170706c 652e7365 72766572 6d677264 d2131415 165a2463 6c617373 6e616d65 5824636c 61737365 73574e53 4572726f 72a21517 584e534f 626a6563 745f100f 4e534b65 79656441 72636869 766572d1 1a1b5472 6f6f7480 0108111a 232d3237 3c424b52 5d666d6f 7173758c 919ca5ad b0b9cbce d3000000 00000001 01000000 00000000 1c000000 00000000 00000000 00000000 d5>
caching:RegistrationStatus:errorDescription = "The operation couldn’t be completed. (com.apple.servermgrd error 1.)"
caching:RegistrationStatus:errorCode = 1

caching:RegistrationStatus = 0

This is usually because the server cannot make a connection to Apple. Check that the server can ping, or access the suconfig.apple.com server. Most of the time I’ve found that this involves a proxy. To sanity check for this in a script, try and curl down a copy of http://suconfig.apple.com/resource/registration/v1/config.plist.

There’s more, but I’m out of time. Will come back to this.