Mass Deployment

Deploying and Managing Firefox Part 2: Working with Munki

A special thanks to Nick McSpadden for his third submission to krypted.com. With all the new changes in OS X/Server I haven’t even had time to write as many in such a span!!!

This is a follow up post to the Firefox Management guide.

Knowing how to use the CCK to manage Firefox, the next big question is: how do we get this into Munki? It’s unfortunately not as cut and paste as we’d hope, because, with all things, Firefox tends to make us do a bit of work to get what we want from it.

Importing Firefox 10.0.10 ESR (current version as of writing time) into Munki is easy. You can add whatever other stuff you need to the pkginfo, but it tends to take care of itself.

Importing the CCK into Firefox is where this gets fun. Luckily, some very smart people have figured this out, thanks to the MacEnterprise mailing list. See the conversation here: https://groups.google.com/d/topic/macenterprise/YUqrm96QSFo/discussion. Credit goes to Nate Walck for the script and Greg Neagle for the advice.

If you are deploying the CCK into the internal Firefox application distribution directory, then you may notice that a vanilla install of Firefox does not have the Firefox.app/Contents/MacOS/distribution/bundles/ directories. We’ll have to create them as part of the install process.

If you want to put the Firefox CCK files somewhere other than inside Firefox, you’d need to change the add-on scopes for Firefox to load it. This isn’t really ideal either, because it requires micromanaging the Firefox install, which means that every time you import a new Firefox update, you have to do a lot of manual labor to make sure all these preferences get included.

One solution is to repackage Firefox with the CCK itself and deploy that as one. It works just fine, but it’s a lot of work – especially with Firefox’s release schedule. You’d have to rebundle it for Munki every six weeks. Pox on that, I say. But editing Firefox preferences is also undesirable for the extra work it generates.

Greg’s suggestion: a symlink! Throw the CCK anywhere, such as /Library/Application Support/FirefoxCCK/, and then create a symlink into Firefox’s bundles directory.  In this post, I’ll be using the example CCK configuration named “test-sacredsf-cck@extensions.sacredsf.org” as in my last post.

There are a few pieces to this we need to incorporate:

  1. A postinstall script for Firefox that guarantees the establishment of the symbolic link between the CCK location and the internal Firefox bundles directory.
  2. A package for the CCK itself that drops the items in the location you want, with the appropriate installs key to ensure it reinstalls if deleted.
  3. The CCK package should also establish a symbolic link to itself if one does not already exist.
  4. A guaranteed reinstall of Firefox, should it be deleted, that also incorporates the re-establishment of the symbolic link.

We can accomplish part of this in a postinstall script for Firefox in Munki:

#!/bin/bash
mkdir -p -m 755 /Applications/Firefox.app/Contents/MacOS/distribution/bundles/
mkdir -p -m 755 /Library/Application Support/FirefoxCCK/
if [ ! -L /Applications/Firefox.app/Contents/MacOS/distribution/bundles/test-sacredsf-cck@extensions.sacredsf.org ];
then
 ln -s /Library/Application Support/FirefoxCCK/test-sacredsf-cck@extensions.sacredsf.org /Applications/Firefox.app/Contents/MacOS/distribution/bundles/
fi

The if statement above is potentially unnecessary, since it’s unlikely there would be a situation in which Firefox would install but somehow the internal contents of /Contents/MacOS/distribution/bundles/ is preserved, but I figure the extra check won’t hurt.

You can also set this same script to be a postinstall_script for the CCK package, so that if you ever have to add more addons to Firefox, you can guarantee that the symbolic link will be established.

To guarantee the sanctity of our CCK, we’d have to add an installs item to check that the unpacked CCK exists. We check the CCK’s path, and that the CCK’s md5 matches the expected one (so that we can guarantee it hasn’t been changed). The CCK’s existence and its md5 should be installs keys for the CCK itself.  In this case, I do not explicitly call for an installs check on the symlink itself, on the basis that it’s extremely unlikely someone will delete the symbolic link but not Firefox.app.  Unless the user has administrative privilege, they can’t delete either of them anyway.  If your users have administrative privileges, then it doesn’t really make sense to manage Firefox for them.

The installs keys for Firefox:

<key>installs</key>
<array>
 <dict>
  <key>CFBundleIdentifier</key>
  <string>org.mozilla.firefox</string>
  <key>CFBundleName</key>
  <string>Firefox</string>
  <key>CFBundleShortVersionString</key>
  <string>10.0.10</string>
  <key>minosversion</key>
  <string>10.5</string>
  <key>path</key>
  <string>/Applications/Firefox.app</string>
  <key>type</key>
  <string>application</string>
 </dict>
</array>

The installs keys for the CCK package (obviously you’ll need to change your checksum accordingly):

<key>installs</key>
 <array>
 <dict>
 <key>path</key>
 <string>/Library/Application Support/FirefoxCCK/test-sacredsf-cck@extensions.sacredsf.org</string>
 <key>type</key>
 <string>file</string>
 </dict>
 <dict>
 <key>md5checksum</key>
 <string>8c994a5e24ebee8f8227f5d2e37b97dc</string>
 <key>path</key>
 <string>/Library/Application Support/FirefoxCCK/test-sacredsf-cck@extensions.sacredsf.org/cck.config</string>
 <key>type</key>
 <string>file</string>
 </dict>
 </array>

We do it this way to guarantee that the CCK is always linked to the correct place in Firefox, even if Firefox is updated, or installed separately. Since Firefox always creates the symlink as part of its install, we don’t have to worry about it breaking if the user deletes Firefox, or Firefox gets updated to a new version (which won’t have the directories or symlink inside it by default).

The CCK will only get reinstalled if it’s missing from the /Library/Application Support/ folder (or wherever you initially stashed it).

This way, as long as the CCK is listed as an update-for for Firefox, you’ll always guarantee that the correct Firefox management is installed.  The only thing you need to remember to do is copy the postinstall_scripts to each new version of the Firefox and CCK pkginfos (although the CCK pkginfo will need a new checksum if you make changes).