AFP548

The Commandments of Packaging in OS X

Whether you're a Mac Developer or Systems Admin, you've probably had to package up a bundle of files for deployment onto a number of machines.  There are many ways to do this with just as many software options; it's easy to get confused and make some simple mistakes.  The current trend away from deploying software into a monolithic "Golden Master" image and toward a modular package-based approach is pushing (or SHOULD BE pushing) Devs and DevOps folk to rethink the way they package. You can't automatically assume that a package will always be installed interactively on the boot volume through the GUI (could you ever really?), but that still doesn't stop certain developers from doing so.

Read on for more… 

Because of this, I've tried to compile a list (call them 'Commandments' if you must) of rules to abide by when you're packaging files for installation/deployment in OS X.   Many of these commandments stem from the fact that sometimes packages aren't going to be installed on the boot-volume of the system.  Tools like InstaDMG, System Image Utility, and even the act of installing packages from the command line will install packages to a separate volume or Disk Image.  In this vein, running scripts that test against the currently booted OS produce unintended results (at best). In the end, whether you need to package up a bunch of fonts or the next killer app, and whether you're double-clicking on the package to install it or deploying it via Munki, InstaDMG, Puppet, Filewave, LANRev, or whatever, it should STILL WORK with your deployment method of choice. These guidelines should lead us all to that end result: installing software quickly and efficiently via your chosen method without damaging your system. Many thanks go out to the many members of the Macenterprise Mailing list for providing many of these rules.  I can only take credit in compiling these rules, and not coming up with them on my own.   

1.  Do not assume that your package will be installed interactively via the GUI or on the currently booted volume.
This rule encompasses the core of my argument above; some of the better (and finer) points were:

2.  Unnecessary actions are unnecessary.
If that sounds a little redundant, try installing a package that opens a browser window to the installed-software's homepage.  Some packages also do "helpful" things like using osascript to open a finder window showing their newly-installed Application.  The problem with this is that if you install this package at the loginwindow, then a Finder window (opened by root, no less) is spawned behind the loginwindow.  Someone logging in right after the package is installed now has a finder window with root permissions.  Also, with regard to unloading kext files, Karl Kuehn has a great piece of advice, "If you need to do something like unload/load a kext, then you might want to pay attention to whether you are actually installing on the boot volume or not. This can be done by looking to see if the target volume ($3 in bash) is "/" or not. If it is not, then you don't want to go playing with kext-commands. You probably also want to check for the COMMAND_LINE_INSTALL variable, as this means that the user is probably not aware that something is going on. A complicating factor is that InstaDMG will in some cases wrap thing in a chroot jail, so the test for target volume is not always completely accurate (but we do set the COMMAND_LINE_INSTALL flag)."  Similar suggestions of this nature were as follows:

3.  Licensing should have the option to be managed by Systems Administrators.
Licenses are manageable through the GUI, but the option for centrally managing licenses should exist transparently to the end user.  Whether you allow for a scriptable licensing interface, separate license files that exist OUTSIDE of the user's Home Directory, or license files controlled through preference manifests and MCX, there should be an option for Systems Administrators to license your software without prompting the user to enter a code.  Not only does this solve management and deployment issues, but it allows for separate installation and licensing packages to thwart unauthorized installation.  

4. Use pre/post-install scripts only when necessary (and heed all other rules with your scripts).
Pre and Post-install scripts can be very helpful in specific situations, but if your intentions are to install files it's best to do that within a payload.  Many folks who use tools like Radmind, Puppet, Lanrev, and et cetera rely on having specific loadsets for every package.  It's much easier to use lsbom on a package and see exactly what will be installed rather than waiting for some third-party voodoo or post-install script to modify files (and then have to use fsevents to see what has changed).  Karl Kuehn once again provides some invaluable information: "If you can't avoid asking the user a question during the install (there are very, very few cases where this is actually acceptable), and can't put it in an installer plugin (note: these are not run with command-line installs), then you should probably be checking for the COMMAND_LINE_INSTALL environmental variable. If it is set, then you should avoid whatever it was you were going to do. If you can't do this for some reason, then it is time to go back to the drawing board (or developers) and figure it out again."

5.  Be true to the Operating System.
This nebulous rule covers all relevant suggestions dealing with the operating system onto which you're installing your package.  If you're going to support OS X back to version 10.4, then it goes without saying that you should TEST your package on every version from 10.4 up to the most current version.  

6.  Naming Conventions are Necessary and Helpful.
Give your packages meaningful names and version numbers.  VPN.pkg is NOT helpful.  Providing your vendor and product name, along with important version numbers, will make Systems Administrators VERY happy when they try to sort out lists of packages.  

So there you have it, an extensive (yet most likely INCOMPLETE) list of some of the biggest gripes from Sysadmins who have to maintain more than one Mac in their organization.  Please forgive the little errors (such as post-install instead of postinstall, if you prefer) and feel free to comment to your heart's content.  Hopefully those who package applications will read this and change their ways.  Until then, I'll be with everyone else who needs to repackage some Crappy App whose package installer just won't work…

Exit mobile version