AutoPkg recipe writing: things to look out for

AutoPkg is a cool project for Mac admins (in theory, Windows admins could use it, too, and there are even a few Windows recipes). Although it's a flexible framework that can be applied in many different ways, what it's most useful for is automating the tedious process of going to a website, downloading a new version of the software, and then importing that download into whatever you're using to push updates out to your Mac clients.

For a while, I was using existing recipes (there are many, so this is a totally valid approach), but eventually there was software I didn't see recipes for, so I started writing my own recipes. At first, I just started by copying existing templates and just modifying certain parts (the download URL, or the regular expressions to search for within the search URL).

Here are some things I noticed, in case you ever want to write your own recipes and run into these issues.

Arguments need to be separate

I ran into this issue where I was trying to purge the destination before unarchiving a .zip file, but it didn't seem to be working. Even though the archive_path and destination_path seemed to work fine without being in the Arguments dictionary, the purge_destination key wasn't registering until I put them all into the Arguments dictionary, as I should have from the start... so, remember to always put all arguments in an actual Arguments dictionary. Example:

<dict>
<key>Processor</key>
<string>Unarchiver</string>
<key>Arguments</key>
<dict>
<key>purge_destination</key>
<true/>
<key>archive_path</key>
<string>%RECIPE_CACHE_DIR%/downloads/%NAME%.zip</string>
<key>destination_path</key>
<string>%RECIPE_CACHE_DIR%/%NAME%/</string>
</dict>
</dict>

Code signature verification within disk images

When you're doing code signature verification on a disk image, you don't have to explicitly use the DmgMounter processor to mount the disk image. Instead, you can just treat the .dmg as a folder that includes the bundle to be verified. Here's an example (where %pathname% refers to the downloaded .dmg):

<dict>
<key>Processor</key>
<string>CodeSignatureVerifier</string>
<key>Arguments</key>
<dict>
<key>input_path</key>
<string>%pathname%/DiskMaker*.app</string>
<key>requirement</key>
<string>identifier "net.gete.diskmakerx" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "2U4ZFMT67D"</string>
</dict>
</dict>

Dealing with regular expressions

If you're not a regex expert, some of the regular expression searches for the URLTextSearcher processor may look like gibberish to you.

A few tips to help with that, apart from (or maybe in addition to?) reading up on all the details of the Python regex documentation:

  • Before you put the regex into your recipe, you can test out your regex using Regex101 (select the Python one).
  • Generally speaking, the most useful thing I've found is creating a capture group with
    (?P<nameofcapturegroup>bunchofregex)
  • Just as you're about to put the regex into your recipe, make sure to substitute &lt; for < and &gt; for >

Script AutoPkg trust verification and trust update process

Starting with version 1, AutoPkg began evaluating trust info for recipes, so you could see what changes were made to a recipe (if changes were made) and then accept the changes if you wanted to. Here is what the typical trust verification workflow looks like.

Whether running a list of recipes via script or via AutoPkgr schedule, I'd occasionally get error'ed recipes when trust was broken, have to manually run

autopkg verify-trust-info -vv NAMEOFRECIPE
and then, after review, run
autopkg update-trust-info NAMEOFRECIPE
and then run the recipe after updating the trust info:
autopkg run -v NAMEOFRECIPE
So I thought I'd take a stab at scripting the whole process. Basically my script updates all the repos (to see if there are changes), verifies trust info on each of the recipes in the recipe list, and then prompts the user to review changes and approve them or not, before running all the approved or unchanged recipes.

It's still in the early testing phase, but it seems to work so far....

Automating an AutoPkg Munki import when vendors don’t package installers properly

You may have, when using (or creating) a .munki AutoPkg recipe, come across a situation in which you run it:

autopkg run -v NAMEOFITEM.munki
and then get something back like this:
Item NAMEOFITEM already exists in the munki repo as OLDNAMEOFITEM.
even though you're sure the item is newer than the one in the Munki repo.

That has to do with the find_matching_item_in_repo() function the MunkiImporter processor uses to determine whether the item exists already or not.

It compares a number of things between the to-be-imported item and what's already in the Munki repo—installer item hash, installs, receipts, files and paths, etc. If any of those matches up, MunkiImporter considers it a match.

So, for example, if you have BADLYPACKAGEDBYVENDOR 3.7.3, which is an update for BADLYPACKAGEDBYVENDOR 3.7.2, but the receipts for both are just 1 (yes, 1 and not 3.7.2 or 3.7.3), the MunkiImporter processor will see the two as the same and not do "another" import of the same item. Likewise, if the version in the app bundle is 3.7 and not 3.7.2 or 3.7.3, the MunkiImporter processor will see them as the same. I've even run into situations in which a vendor artificially ups the number but the "new" package or .app bundle is exactly the same. In that case, the installer hash will be the same, and the MunkiImporter processor will see them as the same.

So what do you, apart from complain to the vendor and pray it fixes the problem?

There may not be anything you can do apart from force an import. You may find a convoluted workaround, though. For LockDown Browser, I had to create an installs array based on the executable and also essentially override the useless receipts array. You might have to do something similar, depending on how bad the vendor package is.

When an AutoPkg recipe fails to import a .dmg

If you ever have an AutoPkg recipe that seems to be working fine for weeks or even months and then suddenly fails with a message like this one:

Error in local.munki.FileZilla: Processor: MunkiImporter: Error: creating pkginfo for
/Users/USERNAME/Library/AutoPkg/Cache/local.munki.FileZilla/FileZilla.dmg failed: Could not mount
/Users/USERNAME/Library/AutoPkg/Cache/local.munki.FileZilla/FileZilla.dmg!
(doesn't have to be FileZilla—could be anything), you may not see the .dmg is mounted in Disk Utility (or even diskutil list), but you can check to see if it's a phantom mount by seeing if it shows up in the output of
hdiutil info
If it does show up there, then run
hdiutil detach /dev/diskFILLINLOCATION
and then re-run the recipe. Should be fine after that.

Acknowledgements: Thanks to Eric Holtam for the tip—just documenting it here for anyone else who may benefit from it.

AutoPkg and Munki with UnRarX

AutoPkg and Munki are a great combination to keep client machines updated with the latest versions of software. UnRarX (at least as of this writing) has kind of a funky situation with AutoPkg, though. The AutoPkg download recipe is currently downloading the beta of 2.2 instead of the final release of 2.2.

What makes this complicated are a few things:

  • When you launch up UnRarX 2.2B, the app itself checks for an update and then prompts you to upgrade to UnRarX 2.2.
  • The binary for 2.2B and 2.2 is exactly the same (if you do an MD5 check on /Applications/UnRarX.app/Contents/MacOS/UnRarX for both version, they turn up the same hash).
  • If you do a
    makepkginfo -f /Applications/UnRarX.app/Contents/Info.plist
    an installs array with the CFBundleVersion will come up instead of an MD5 checksum on the file itself.
  • As far as Munki's concerned, 2.2B is a higher version number than 2., which makes sense.

It's a bit of a mess, because 2.2B appears to be higher than 2.2, but it's essentially the same binary as 2.2... and it prompts you to upgrade to 2.2 when you launch it.

So how do you get your 2.2B clients "upgraded" to 2.2? I had to do a few things.

First of all, I got the output of

makepkginfo -f /Applications/UnRarX.app/Contents/MacOS/UnRarX
just to get the basic format for the installs array.

Then I ran

md5 /Applications/UnRarX.app/Contents/Info.plist
on each version to get the unique checksum, and I modified the installs array to point to that file and to use that hash instead of the one for the executable.

Finally, I changed the version number in Munki of the 2.2B to 1.0 (or some other arbitrarily lower number than 2.2).

Once I did that, my clients says 2.2 as an upgrade to the existing 2.2B and then upgraded. I've also had to temporarily turn off the AutoPkg recipe for UnRarX, because the Sparkle feed is still showing 2.2B.

AutoPkg Adobe Flash Player recipes, licenses, and Munki

13 October, 2016 update: Adobe just broke this by making the distribution page require an Adobe ID login before you can view it.

Even though Flash is slowly being deprecated, people still use it. And while people still use it, Mac admins keep having to make sure their users' Adobe Flash Player plugins are up to date so the plugin is the smallest security hole that it can be.

Adobe Flash Player is free to download, but Adobe would like you to apply for a license to distribute Adobe Flash Player. Once you do that, they send you a unique link to download a distributable Flash Player (which is not materially different from the normal one you would download without the license).

One AutoPkg recipe maintainer wrote up a series of recipes to deal with this type of download. Here's one example.

For some reason, even though that recipe works to download Flash Player, I wasn't able to get it to work to download Flash Player and then have Munki import the approved download into the Munki repo.

So, as a workaround, I made a hodge-podge recipe combining the general Adobe Flash Player download AutoPkg recipe with the proper one, and then modifying it to include my institution's unique download link.

If you can get DLA to work with your Munki recipe, ignore the suggested code below (and comment to let me know how you did it). Otherwise, you may want to make an override for the standard Flash download recipe, and then paste in the following, and modify the link to be your institution's unique download link:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Description</key>
<string>Downloads Adobe Flash Player installer.</string>
<key>Identifier</key>
<string>com.github.autopkg.download.FlashPlayer</string>
<key>Input</key>
<dict>
<key>NAME</key>
<string>AdobeFlashPlayer</string>
</dict>
<key>MinimumVersion</key>
<string>0.6.0</string>
<key>Process</key>
<array>
<dict>
<key>Processor</key>
<string>URLTextSearcher</string>
<key>Arguments</key>
<dict>
<key>url</key>
<string>https://YOURORGANIZATIONSUNIQUEURL</string>
<key>re_pattern</key>
<string>Flash Player (?P&lt;version&gt;.*?) \(Win .*?Mac\)&lt;\/span&gt;</string>
</dict>
</dict>
<dict>
<key>Processor</key>
<string>URLTextSearcher</string>
<key>Arguments</key>
<dict>
<key>url</key>
<string>https://YOURORGANIZATIONSUNIQUEURL</string>
<key>re_pattern</key>
<string>(?P&lt;downloadurl&gt;https.*?osx_pkg.dmg)</string>
</dict>
</dict>
<dict>
<key>Processor</key>
<string>URLDownloader</string>
<key>Arguments</key>
<dict>
<key>url</key>
<string>%downloadurl%</string>
<key>filename</key>
<string>%NAME%.dmg</string>
</dict>
</dict>
<dict>
<key>Processor</key>
<string>EndOfCheckPhase</string>
</dict>
<dict>
<key>Processor</key>
<string>CodeSignatureVerifier</string>
<key>Arguments</key>
<dict>
<key>input_path</key>
<string>%pathname%/Install Adobe Flash Player.pkg</string>
<key>expected_authority_names</key>
<array>
<string>Developer ID Installer: Adobe Systems, Inc.</string>
<string>Developer ID Certification Authority</string>
<string>Apple Root CA</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

I paired that with this Munki recipe override:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Identifier</key>
<string>com.github.autopkg.munki.FlashPlayer</string>
<key>Input</key>
<dict>
<key>MUNKI_REPO_SUBDIR</key>
<string>internet_plugins</string>
<key>NAME</key>
<string>AdobeFlashPlayer</string>
<key>pkginfo</key>
<dict>
<key>catalogs</key>
<array>
<string>testing</string>
</array>
<key>description</key>
<string>Adobe® Flash® Player is a cross-platform browser-based application runtime that delivers uncompromised viewing of expressive applications, content, and videos across screens and browsers.</string>
<key>display_name</key>
<string>Adobe Flash Player</string>
<key>name</key>
<string>%NAME%</string>
<key>unattended_install</key>
<true/>
</dict>
</dict>
<key>ParentRecipe</key>
<string>com.github.autopkg.download.FlashPlayer</string>
<key>Process</key>
<array>
<dict>
<key>Processor</key>
<string>MunkiPkginfoMerger</string>
<key>Arguments</key>
<dict>
<key>additional_pkginfo</key>
<dict>
<key>version</key>
<string>%version%</string>
</dict>
</dict>
</dict>
<dict>
<key>Arguments</key>
<dict>
<key>pkg_path</key>
<string>%RECIPE_CACHE_DIR%/downloads/%NAME%.dmg</string>
<key>repo_subdirectory</key>
<string>%MUNKI_REPO_SUBDIR%</string>
</dict>
<key>Processor</key>
<string>MunkiImporter</string>
</dict>
</array>
</dict>
</plist>

Disable auto-updates for Firefox when deploying using Munki and AutoPkg

Note before you begin
Acknowledgements
Why you should do this
The actual procedure
Caveat
Thunderbird
The CCK2 method

Note before you begin

If you know nothing about Munki or AutoPkg, then this page will be of little use to you. If you're interested in a basic setup tutorial, check out the Absolute beginner’s guide to setting up Munki (not monkey).

Acknowledgements

Special thanks to Nick McSpadden for Deploying and Managing Firefox Part 2: Working with Munki, which lays out the disable-update concept with a slightly different procedure (using CCK and symlinks), and to Mozilla for documenting directory changes in Deploying Firefox in an enterprise environment.

Why you should do this

For a while, I was deploying Firefox using Munki but then not disabling updates, because it actually wasn't causing any problems.

firefoxupdateerror
Recently, though, users have been getting this kind of error, which is odd, because Firefox should, in theory, still be able to update itself, even if Munki has been pushing updates, because all Munki does is essentially automate the regular installation process (dragging the Firefox.app bundle to the /Applications folder).

The actual procedure

Create a text file with these contents:

pref("general.config.filename", "mozilla.cfg");
pref("general.config.obscure_value", 0);
Save that text file as autoconfig.js

Create a second text file with these contents:

// Disable updater
lockPref("app.update.enabled", false);
// make absolutely sure it is really off
lockPref("app.update.auto", false);
lockPref("app.update.mode", 0);
lockPref("app.update.service.enabled", false);
Save that text file as mozilla.cfg.

Create a DisableFirefoxUpdates package (if you prefer a GUI, I'd recommend Packages) that distributes a payload of two files. I decided to put the files in /Library/Application Support/Mozilla/DisableAutoUpdates, but you can put them somewhere else, as long as you can find them later (if you do decide on a different location, make sure to tweak the scripts below accordingly).

Import the DisableFirefoxUpdates package into Munki (using munkiimport) and then make it a requirement for the Firefox package.

You may also want to add this as a post_install script for DisableFirefoxUpdates:

#!/bin/bash

# Distribute the script if Firefox is already installed
if [ -d "/Applications/Firefox.app/Contents/Resources" ]; then

# Copy the autoconfig.js
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/autoconfig.js /Applications/Firefox.app/Contents/Resources/defaults/pref

# Copy the mozilla.cfg file
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/mozilla.cfg /Applications/Firefox.app/Contents/Resources/

fi
That's handy if you, like me, are starting to distribute the DisableFirefoxUpdates package after having already deployed Firefox.

There is one more final step, which is super important. If you're using AutoPkg (or its graphical frontend, AutoPkgr) to automatically get the latest Firefox and import it into Munki, you want to create an override recipe (if you have one already, tweak the existing override), and then include the following as part of the pkginfo dict:

<key>postinstall_script</key>
<string>#!/bin/bash

# Copy the autoconfig.js
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/autoconfig.js /Applications/Firefox.app/Contents/Resources/defaults/pref

# Copy the mozilla.cfg file
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/mozilla.cfg /Applications/Firefox.app/Contents/Resources/
</string>
What this does (minus the check to see if Firefox is installed) is just make sure that every time you install a new version of Firefox, you copy the DisableFirefoxUpdate files over to the newly-installed version.

Another way to approach it would be to have the Munki item disabling auto-updates also have an installs array in its pkginfo, so that if the new Firefox overwrites it, Munki will reinstall (here's an example):

<key>installs</key>
<array>
<dict>
<key>md5checksum</key>
<string>326b871936cca29e198fdcaf50371e90</string>
<key>path</key>
<string>/Applications/Firefox.app/Contents/Resources/mozilla.cfg</string>
<key>type</key>
<string>file</string>
</dict>
<dict>
<key>md5checksum</key>
<string>0377ceecfff0b937c590f3ae1770e8f6</string>
<key>path</key>
<string>/Applications/Firefox.app/Contents/Resources/defaults/pref/autoconfig.js</string>
<key>type</key>
<string>file</string>
</dict>
</array>
That installs array is a combination of the results of these commands:
/usr/local/munki/makepkginfo -f /Applications/Firefox.app/Contents/Resources/defaults/pref/autoconfig.js
/usr/local/munki/makepkginfo -f /Applications/Firefox.app/Contents/Resources/mozilla.cfg

Caveat

I've done some testing, and this works. The only thing to keep in mind is that if you deploy the DisableFirefoxUpdates after having already deployed Firefox to users, users will still likely have auto-updates enabled... until they restart Firefox.

So if a user says "I'm getting an error about Firefox not updating," have the user quit out of Firefox and launch up Managed Software Center, and it should be good from that point forward.

Thunderbird

Someone asked about this, so I did testing, and this exact same config works for Thunderbird as well. You would just have to add in the appropriate script to copy the files over (from the same payload):

#!/bin/bash

# Distribute the script if Thunderbird is already installed
if [ -d "/Applications/Thunderbird.app/Contents/Resources" ]; then

# Copy the autoconfig.js
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/autoconfig.js /Applications/Thunderbird.app/Contents/Resources/defaults/pref

# Copy the mozilla.cfg file
cp /Library/Application\ Support/Mozilla/DisableAutoUpdates/mozilla.cfg /Applications/Thunderbird.app/Contents/Resources/

fi

The CCK2 method

If you would like to use CCK for some more major customizations instead of just disabling auto-update, here is a recent blog post on how to do so:
Firefox, CCK2 and an AutoPKG Recipe.

Here are a few fun screenshots of my own to complement the ones on that page:

And this is the Munki recipe you'd use with the resulting autoconfig.zip file.

Absolute beginner’s guide to setting up Munki (not monkey)

16 November, 2017 update: I'm actually going to recommend against using the guide below. It worked for me. It's what I wish I'd had when I started using Munki three years ago. But since then I've found the number of pieces to be confusing to new users. That and AutoPkgr, for all intents and purposes, ceasing development make me want to not recommend the tutorial below any more.

Start with the Demonstration Setup on the Munki wiki and really try to understand what's going on first with Munki before you do anything else.

Once you have a good handle on the basics of Munki, you can start exploring other things like MunkiAdmin and AutoPkg.

Some great resources if you have questions when setting up Munki are the Munki Discuss mailing list and the #munki channel on the MacAdmins Slack.

Table of Contents

Why this guide?
What is Munki?
What are the basic requirements for this setup?
Install on the server Mac the needed software
Prepare the server to be a Munki software repository.
Use MunkiAdmin to set up your repositories, catalogs, and manifests.
Import software into your repository manually
Figure out your server Mac's IP address
Set up the Munki client
Set up AutoPkgr

Why this guide?

While there's no dearth of comprehensive guides to Munki out there, many of them are too comprehensive (to the point of being potentially overwhelming to new users). The focus of this guide is to get you up and running with Munki, not to give you a comprehensive, in-depth explanation of everything Munki can and cannot do.

Interested in the more comprehensive guides instead? Check out the following links:

Still here? Okay. Let's proceed with the non-comprehensive guide...

Return to top

What is Munki?

Munki is a tool to deploy software out to Mac clients. You can force updates from the server or create optional software for clients to install themselves.

Return to top

What are the basic requirements for this setup?

  1. One Mac (OS X 10.8 or higher) that can act as a server (yes, you can actually run the server on Linux, Windows, etc., but again—the point of this tutorial is to get you up and running in at least one fashion and not to provide a comprehensive guide to all use cases).
    N.B.: you do not have to have OS X Server installed or have an actual Xserve machine. It can be any Mac that you want to repurpose as a Munki "server."
  2. At least one Mac that can act as a client (you will, supposedly, have many clients eventually).
  3. The latest Munki Tools release (this is the same installer for both the client and the server, but we'll tweak the installation slightly for the server).
  4. The latest MunkiAdmin release (not necessary for Munki operations in general but necessary for this tutorial).
  5. The latest AutoPkgr release (again, not necessary for Munki but extremely helpful).
  6. A working Internet connection... of course.

Return to top

Install on the server Mac the needed software

On the Mac that's going to be the server hosting the software, install all three downloads.

MunkiAdmin

munkiadmin Once you double-click the .dmg for MunkiAdmin, it's a simple drag-and-drop to the Applications folder (option to copy to Utilities instead, if you'd prefer).

AutoPkgr

autopkgr Double-click the .dmg for AutoPkgr and then drag and drop that to the Applications folder. (As mentioned before, AutoPkgr is not necessary for Munki but it is helpful—if you find the AutoPkgr bits confusing, you can skip it for now.)

Munki Tools

Munki Tools has more of a wizard-style installer.

munkis01 Click Continue.

munkis02 You probably have only one drive you want to install to, but if you have two or more, pick the one you want, and then click Continue.

munkis03 For the server, click Customize.

munkis04 Uncheck Managed Software Center and Munki launchd agents, and make sure Munki core tools and Munki admin tools are checked.

munki11b Authenticate with an admin username and password. Then click Install Software.

munkis06 Click Close.

Return to top

Prepare the server to be a Munki software repository.

The standard in all the guides is to put the Munki repository in the shared users folder and then create a symlink to the web server directory (the equivalent of /var/www or /var/www/html for you Linux geeks out there). For consistency's sake, we'll keep that standard here, but if you're dedicating this machine to being a Munki repository, there isn't any reason you couldn't just make the repository directly (not just symlinked) in the web server directory.

We're still on the server Mac (until further notice).

Open up the Terminal.app (you can find it in /Applications/Utilities or search for it with Spotlight).

Then, paste in these commands:

cd /Users/Shared
mkdir -p munki_repo/catalogs
mkdir munki_repo/manifests
mkdir munki_repo/pkgs
mkdir munki_repo/pkgsinfo
mkdir munki_repo/icons
chmod -R a+rX munki_repo
sudo ln -s /Users/Shared/munki_repo /Library/WebServer/Documents/
sudo apachectl start

To sum up (in case you don't speak bash), we just created a directory and a few subdirectories for Munki business, made sure the proper permissions on that directory are in place, made a symlink to that directory from the web server directory, and then started up the Apache web service.

Note: If you're using OS X Server, the path is slightly different—more details at Setting Up Munki With OS X Yosemite Server.

You may also want to configure munkiimport:

/usr/local/munki/munkiimport --configure
It will ask you some questions. For Repo URL, put in file:///Users/Shared/munki_repo, since that's where we just created the Munki repository location.

For the Repo access plugin, leave it blank. The rest you can decide for yourself or just stick with the defaults by hitting Return/Enter instead of typing something in. (Personally, I prefer a .plist extension and TextWrangler.)

Return to top

Use MunkiAdmin to set up your repositories, catalogs, and manifests.

Launch up MunkiAdmin (you installed this earlier).

munki07
When it launches up the first time, it'll immediately prompt you to Select a munki Repository. Go ahead and navigate to the /Users/Shared/munki_repo directory and then click Open.

Once you do that, it should be fairly empty, that's because all you have are the empty directories you'd created earlier.

You may want to make it so that MunkiAdmin remembers your repository instead of asking you every time at startup which repository you want to use.

munki07a Go to MunkiAdmin > Preferences....

munki07b Then, next to On Startup, select Open previous repository.

munki07c Once that's selected, you can close the Preferences window.

munki08 Go to File > New Catalog. The catalogs are general lists of what software is available in the repository—a sort of table of contents.

munki09 Call your new catalog production.

I'd also recommend creating a testing catalog. That's what most AutoPkg recipes will default to, and it's a good idea in general to have a set of testing clients install updates or new packages before you move the packages into production.

munki10 Go to File > New Manifest. Manifests pick out of the larger catalog(s) and then select software available to certain users. Each machine should have its own individual manifest, but each individual manifest can also include other manifests.

munki11b Call your new manifest the serial number of your test machine.

Note: Why the serial number? I explain more about this in Another opinionated guide to Munki manifests.

Return to top

Import software into your repository manually

One way to get software into your repository is manually—you download Firefox, for example, and it comes as a .dmg file.

munki12
In (still) MunkiAdmin (still on the server Mac), go to File > Import Items.

munki13 Find your .dmg file and open it.

munki14 Save it, when prompted.

munki15 You may see a dialogue pop up that says Status: Running makepkginfo.

munki16 When prompted to save, save again.

Note: With a lot of basic packages, it's fine to import it this way using MunkiAdmin. I've found that some packages import better using the command line (e.g., Adobe Creative Suite), so you may—after you get the swing of the point-and-click way—want to try using munkiimport at the command line instead).

munki17 If you go to catalogs (Cmd-2), you'll see your production catalog. If you click on production, you should see your one imported package there unchecked. If you want to include that package in your catalog, check (or tick) the box next to it. Then click the Save button above it.

munki18b Same deal if you go to manifests (Cmd-3), you'll see your serial number manifest that's empty.

You'll also see some different categories within the manifest. Managed Installs is for software you want definitely installed (Managed Uninstalls is for software you want definitely removed). Managed Updates are for software you definitely want updated (whether originally installed through Munki or not). Optional Installs are items you want the clients to have the option to add or remove. Click on the category you want to add the package to.

munki19 If you click the + (plus sign) near the bottom, you can now select the package you'd previously added to your catalog.

munki20b Again, click the Save button to save your changes.

Return to top

Figure out your server Mac's IP address

Here are four ways to do that. I'd recommend

ifconfig

in the Terminal.app as the quickest method.

Make a note of the IP address. We'll need that later for the Munki client(s).

Note: if you are on a domain, you can also use your server Mac's host name to reference it instead of using the IP address (e.g., munki.yourorganization.edu).

That's it for the server side (for now... until we come back for AutoPkgr).

Return to top

Set up the Munki client

As I mentioned before, Munki Tools is the same setup package, whether you're on the server Mac or the client Mac.

munkis07 So for the client Mac, just install those tools (you don't need the Munki admin tools here). This time, however, you will have to reboot immediately after installation.

Then, in the Terminal.app, put in your own version of this command:

sudo defaults write /Library/Preferences/ManagedInstalls SoftwareRepoURL "http://192.168.1.50/munki_repo"

where 192.168.1.50 is whatever your actual IP address is for the server Mac. For the sake of this demo, we're using http, but you may want to check out Using Munki With SSL Client Certificates or Using Basic Authentication for details on using https instead.

The Munki client should check in with the server every hour or so (not exactly an hour—there's a random bit of time tacked on so if you have a bunch of clients checking in at once, they're not clobbering the server together).

managedsoftwarecenter But you can also manually check for updates by going to Managed Software Center (in your Applications folder).

Return to top

Set up AutoPkgr

As we saw with the Firefox example above, you can manually import packages. There are, however, repositories for software that's pre-packaged and ready to work with Munki. These AutoPkg repositories of "recipes" can be especially helpful, for example, if you want to automatically push out updates to Flash and Java, and you don't want to deal with the promotion-ware Adobe and Oracle sometimes include in the installer.

(By the way, AutoPkgr is just a graphical frontend for AutoPkg, the command-line tool.)

You should already have AutoPkgr installed from a previous step, but here's a handy link in case you need to install it on your server Mac right now.

autopkgr01 When you launch up AutoPkgr the first time, you may be prompted for your password a couple of times. Go ahead and authenticate.

Once it's launched, it will have little red dots letting you know Git and AutoPkg are not installed. Go ahead and start with clicking Install Git.

autopkgr03 You'll see it download Git and then start installing Git. At a certain point, it may prompt you for your password. Go ahead and authenticate.

autopkgr04 Then click the Install AutoPkg.

autopkgr05 Same deal. Let it download and try to install. Authenticate, when prompted.

autopkgr07 Once they're both installed, you may want to change the other settings below. I like to check Launch AutoPkgr at login, for example. You may or may not want to hide in the Dock—your choice.

autopkgr08 There are a bunch of recipe repositories. If you're unsure where to start, just check the first one, and it will give you a good, basic selection of software. Obviously, the more repositories you check, the more software recipes you'll have available to you.

For this example, we're going to get the Oracle Java 8 package. For our purposes starting out, you'll need to check only the .munki recipes. You can leave the .download, .install, and .pkg recipes alone. Start by creating an override. Overrides allow you to specify other options without touching the original recipe, but they're also important for security (more on that later). autopkgr09a Then, go ahead and check the box next to your override.

Then, skip over Schedule for now, and go straight to Folders & Integration.

autopkgr11 AutoPkgr will just use what's grayed out, but if you want to change any of these directories for the integration piece, you may want to click Choose.

autopkgr12 Then you can choose your Munki repo.

autopkgr13 You'll see it's essentially the same except in black instead of gray.

Then go ahead and go to Schedule.

autopkgr14 Check both Run AutoPkg every 24 hours and Check for repo updates before each AutoPkg run.

N.B.: Please make sure you read AutoPkg and recipe parent trust info to get more information on a workflow for auditing changes to recipes.

autopkgr15 autopkgr16 It will run automatically in the background, but this first time, you may want to manually run both processes. Again, there may be a password authentication. Just roll with it.

autopkgr17 If everything worked, you should return to MunkiAdmin and see your OracleJava8 package in your Munki repo, ready to be added to a catalog and to a manifest (if you don't, click Reload).

Acknowledgements

Special thanks to Munki creator Greg Neagle for creating Munki but also for having a look this page and suggesting a couple of minor tweaks. Thanks also to the open source community surrounding Munki, AutoPkg, and another fun Mac-admin tools.