The short version:

Deploying MATLAB_R2016a with Munki (Github)

The longer version:

MATLAB, from MathWorks, is a computing environment and proprietary programming language. It has many, many applications, but is primarily used for solving engineering and scientific problems. My organisation, a research institution, sees such high demand for the product that it purchased a Total Academic Headcount (TAH) site license some time ago. Accordingly, packaging the application for deployment is a high priority.

Using Munki, the application is not exactly trivial to deploy. The software is made available as an .iso, on which an is located. This .app can be invoked from the command line, and can also be passed an input file to facilitate an unattended install. So, what are your packaging options?

Packaging options:
  • Install MATLAB on a test machine, configuring for your environment. For example, pointing to your internal license server, and installing the toolboxes for which your organisation is eligible. You then run munkiimport on /Applications/MATLAB_$ to import to your repository.
  • Create an Apple Disk Image of the files required to install MATLAB, and copy this .dmg to your repository. Create a pkginfo file for the application that leverages Munki's postinstall script feature to trigger an unattended install. When a client selects the package for installation, it will download and mount the .dmg, copy the relevant files to /tmp, then run the unattended install. Once complete, the files /tmp are removed and the .dmg unmounted. This method was developed by my former colleague (and author of the excellent Munki-Do), Graham Pugh.

Somewhat predictably, we're using the second option. Why? Here are pros:

  • Repeatable. Theoretically, all you will need is the latest MATLAB.iso to create the .dmg with the install files. MathWorks operate on an annual release cycle, so you should simply just need to drop in a new .iso once a year.
  • Transferrable. The only native OS X process involved in the packaging is hdiutil. You can therefore package from any Mac, avoiding any OS compatibility issues that can arise if taking the local install route.
  • Configurable. You can use the installer-input.txt to control a number of parameters, such as activation properties, log files, and license type (network or standalone).
  • Size. The .dmg is significantly smaller than a packaged .app that contains a number of toolboxes. This saves repository space and network bandwidth.

I stress that this is one approach to packaging and deploying MATLAB. YMMV, etc. It's certainly true that this method is conceptually more complex than simply installing and importing. However, for the reasons above, and a personal preference for the transparency of the process for my colleagues, I prefer this method.

Deployment considerations:

In my organisation, having multiple versions of MATLAB available is essential. To do so, further configuration of the pkginfo is required.

By default, Munki will attempt to use CFBundleIdentifier and CFBundleVersion to determine installation status. If you will only ever be deploying a single version of MATLAB, there is no issue. However, consider the following situation:

  • You make MATLAB_R2015a available to clients.
  • A client installs MATLAB_R2015a.
  • You make MATLAB_R2016a available to clients.
  • Munki sees that com.mathworks.matlab is installed with CFBundleIdentifier of 8.5.0. As MATLAB_R2016a has a CFBundleIdentifier of 9.0.0, Munki will then offer to install the newer version of the app for the user, whether they want it or not.
  • The reverse also demonstrates the issue. A client installs 2016. If 2015 (or any other earlier versions) are available to that client, Munki sees that version 9.0.0 is installed, and will determine that any lower identifier is not eligible for install. Managed Software Centre will therefore present all available versions of MATLAB as installed.

You will therefore need to modify the installs array to use the path and file parameters to determine installation status. The sample pkginfo in my Github repo covers one way to do this.

Any thoughts and/or comments appreciated.