Revisiting appleLoops.py and Managing Additional Audio Content

A few months ago while planning for future macOS upgrades, I realised that the existing methodologies for managing the audio content for GarageBand (and other Apple audio apps) in munki and autopkg were not very well equipped to handle the frequent changes Apple make to the additional content for these apps.

While downloading and importing content for one version of GarageBand would work, this would only be valid for a specific release of GarageBand/Logic Pro X/MainStage, and any time those additional packages were changed by Apple, it would mean revisiting what audio content was imported into munki; while it is possible to simply keep importing packages into munki, and simply mark them as updates for X version of GarageBand, this wasn’t a strategy that I felt was viable for long term deployments. Rather, I needed a solution that met the following criteria:

  • Could be used as a post_install script for munki.
  • Could be run as a script for other deployment tools, or used on its own.
  • Required minimal effort to maintain.
  • Could be used to mirror content locally.

So I decided to re-visit the appleLoops.py tool I had written and turn it into a means of managing the deployment of additional content for these Apple audio apps.

Below is the general outline of how the new appleLoops.py re-write can be used in munki. This assumes a familiarity with munki and related deployment techniques/tools; some minor programming experience in python is handy, but not essential.

The basic process that occurs with any of the three apps is that the first run will trigger a download of mandatory content, once this is installed, the user is given the option of downloading additional content that isn’t essential to the app, but nice to have.
A more in depth explanation of what happens the first time these audio apps launch is available on this Wiki page.

With this information covered, here is my deployment process for munki; note, this process can be adapted to use for deploying the additional content for Logic Pro X and MainStage 3.

  1. Import a GarageBand/Logic Pro X/MainStage 3 app into munki. Typically I use an autopkg recipe that also handles modifying the _MASReceipt/receipt file so the app is not associated with a specific Apple ID.
  2. Use appleLoops.py to download a mirror copy of the additional content for the specific versions being deployed, and place this mirror copy on the munki_repo web server.
    This can potentially be automated to keep the additional content up to date without continuing to manually update the mirror.
  3. Add the appleLoops.py script as a post_install script to the imported app; I find using munkiadmin the easiest way to modify munki’s pkginfo files.
  4. Modify a small snippet of code at the end of the file.
    Change:

    if __name__ == '__main__':
        main()
    

    To:

    if __name__ == '__main__':
        al = AppleLoops(allow_insecure=True, deployment_mode=True, pkg_server='http://munkiserver/munki_repo/pkgs/apple_audio/', dry_run=False, log_path='/var/log', mandatory_loops=True, optional_loops=True)
        al.main_processor()

    The benefit of this is that it is simple to make a change to the post_install script in the relevant munki pkginfo without having to install the script on each client, then maintain it on each client.
    The arguments that are used in the example above are applicable to my environment as there is a local mirror of the additional content that is maintained; you would need to adjust to suit your environment.

While the whole script could be shrunk down to do just the essential parts of deploying the audio content and inserted into deployment tools as either post_install scripts, or other workflow processes in (for example, in JAMF), there are many other features that this updated release includes:

  • Downloading a mirror of the Apple audio content for local hosting.
  • Skips existing downloaded packages to reduce bandwidth usage.
  • Can be run as a scheduled job (either through cron or launchd or other scheduling systems) on the local mirror to download new content.
  • Utilise a Caching Server on the network to dynamically cache loops for deployments.
  • Create DMG’s of downloaded content.
  • Download content for specific releases of Apple’s audio apps.
  • Dry run deployment mode to determine what would be installed or upgraded.
  • Set a free space threshold to avoid filling up local storage when in deployment mode.
  • Silent output during deployment mode.
  • Re-install all previously installed loops.

There are some things to be aware of that currently are limitations or:

  • Each time the script is run in deployment mode, it will look for any of the three apps installed; if one or more is found, it will deploy the content for all the apps found. This means if you’re deploying GarageBand and Logic Pro X together, the first time the script is run, it will deploy the loops for both GarageBand and Logic Pro X; the second time it is run, it will skip any packages already installed.
  • Currently there is no means of providing progress of a post_install script to munki, so any progress UI elements in user facing components of munki will only show that scripts are being run, which for an end user could look as though the progress of the installation has stalled. If you deploy these audio apps as a “self service” deployment with munki, you may wish to take advantage of preinstall_alert to alert users.

Further information can be found on the appleLoops.py wiki.

The latest release is available here.

Support can be found by joining the #musicsupport room in the macadmins Slack.