Apple Configurator,  Apple TV,  Apple Watch,  iPhone,  JAMF,  Mac OS X,  Mac OS X Server,  Mass Deployment,  precache

Tethered Caching of iOS Assets from macOS 10.12.4

There is a new service in macOS, called Tetherator. Tethered-caching is a script that allows you to easily and quickly interact with the tethered-caching service, which has a few kinda’ cool options. This is on a client, and really speeds up all that crazy provisioning stuff you do. It can also check for the presence of a macOS Caching Server and use that as a source for the cache. The tethered-caching script is located at /usr/bin/tethered-caching.

Before you do anything with the service, check the status. That’s done with the -s option (there’s also a -v option to get verbose):

tethered-caching -s

The results before activated should be as follows:

2017-02-28 10:44:45.730 AssetCacheTetheratorUtil[3665:182657] Tetherator is disabled: (no error)
2017-02-28 10:44:45.746 AssetCacheActivatorUtil[3666:182664] Built-in caching server can be activated.
2017-02-28 10:44:45.762 AssetCacheActivatorUtil[3667:182673] Built-in caching server is deactivated: (no error)

Then start the service using the -n option in tethered-caching, along with the IP range to be used:

tethered-caching -n 192.168.1.0

This sets the ListenRanges key in the plist and should result in an activation process that appears as follows:

Starting tethered caching…
2017-02-28 10:47:59.691 AssetCacheActivatorUtil[3848:192902] Built-in caching server can be activated.
2017-02-28 10:47:59.706 AssetCacheActivatorUtil[3849:192910] Built-in caching server is deactivated: (no error)
Filtering the log data using “subsystem == “com.apple.AssetCache” AND messageType == 16″
Timestamp (process)[PID]
2017-02-28 10:48:05.098735-0600 localhost AssetCache[2882]: [com.apple.AssetCache.builtin] Built-in Caching Server activated. Exiting to allow re-launch.
2017-02-28 10:48:05.207493-0600 localhost AssetCache[2882]: [com.apple.AssetCache.builtin] Built-in Caching Server shutting down (0)
2017-02-28 10:48:07.362926-0600 localhost AssetCache[3862]: [com.apple.AssetCache.builtin] Built-in Caching Server version 170 started
2017-03-02 10:45:53.753 AssetCacheTetheratorUtil[29283:2526186] Tetherator enabled.
Started tethered caching. To stop it, press control+c once.

At this point, you’re calling /usr/bin/AssetCacheLocatorUtil to register and then start /usr/libexec/AssetCache/AssetCache via /System/Library/Preferences/Logging/Subsystems/com.apple.AssetCacheServices.plist which defaults read nets:

{Activator = {};
"DEFAULT-OPTIONS" = {
"Default-Privacy-Setting" = Public;
"Enable-Oversize-Messages" = 1;
"Event-Log" = {
Enabled = Inherit;};
Level = {
Enable = Inherit;
Persist = Inherit;};
TTL = {Debug = 0;Default = 10;Info = 10;};};
Daemon = {};
Extensions = {};
Framework = {};
Tetherator = {};}

The AssetCache preferences can be seen by catting /Library/Preferences/com.apple.AssetCache.plist:

Activated = 0;
CacheLimit = 0;
DataPath = "/Library/Caches/com.apple.AssetCache";
LastConfigData = ;
LastConfigURL = "http://suconfig.apple.com/resource/registration/v1/config.plist";
LastPort = 50775;
ListenRanges = ({first = "192.168.1.1";last = "192.168.1.254";});
ListenRangesOnly = 1;
LocalSubnetsOnly = 0;
PeerLocalSubnetsOnly = 1;
Port = 0;
PublicRanges = automatic;
ReservedVolumeSpace = 2000000000;
SavedCacheDetails = {};
SavedCacheDetailsOrder = ("Mac Software","iOS Software","Apple TV Software",iCloud,Books,"iTunes U",Movies,Music,Other);
SavedCacheDetailsStrings = {All the language keys as arrays - which I cut out to truncate the contents of the plist read};
SavedCacheSize = 0;
ServerGUID = "C5F29418-6158-4D3B-9162-XXX";
Version = 1;

Note that in the above, the LastConfigData key is pulled at activation by curling http://suconfig.apple.com/resource/registration/v1/config.plist. I’ve truncated the key as it’s kinda’ long…

A simple command that will be pretty common is to increase the size of the cache. To do so, you’d just edit that CacheLimit key to be the number that you want the cache to be. In the following example, we’re writing the CacheLimit key into AssetCache.plist at 100 gigs:

defaults write /Library/Preferences/com.apple.AssetCache.plist CacheLimit -int 100000000000

There’s also com.apple.AssetCache.builtin.plist in /Library/LaunchDaemons which starts the builtin AssetCache, AssetCacheC, and CacheDelete service.

Once started, you will have a sqlite3 database called AssetInfo.db at /Library/Caches/com.apple.AssetCache. A basic structure of how data is stored includes the following tables:

  • ZAFFINITY with the following column: Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZLASTSAVED TIMESTAMP, ZID VARCHAR
  • ZASSET with the following columns: Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZMD5OFFSET INTEGER, ZTOTALBYTES INTEGER, ZCREATIONDATE TIMESTAMP, ZLASTACCESSED TIMESTAMP, ZCHECKSUM VARCHAR, ZGUID VARCHAR, ZINDEX VARCHAR, ZLASTMODIFIEDSTRING VARCHAR, ZNAMESPACE VARCHAR, ZURI VARCHAR, ZMD5CONTEXT BLOB
  • Z_METADATA with the following columns: Z_VERSION INTEGER PRIMARY KEY, Z_UUID VARCHAR(255), Z_PLIST BLOB
  • Z_MODELCACHE with just the Z_CONTENT column
  • TABLE Z_PRIMARYKEY with the following columns: Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR, Z_SUPER INTEGER, Z_MAX INTEGER

Once enabled, updates will be cached to the computer that the service is enabled on, metadata stored in the previously mentioned database, and then change ports and network ranges when needed.