Skip to content

Recipe Writing Guidelines

Timothy Sutton edited this page Sep 15, 2013 · 16 revisions

The following is a set of guidelines that should be followed when writing your own recipes, especially if you wish to share them with others via a Git repository. The AutoPkg repo- commands make it easy to add and update recipes from others' repos.

Finding examples

There is quite a variety of tasks done to handle many common applications in the AutoPkg's own recipes repo. You can use existing, core AutoPkg processors to do things like:

  • download and cache from a URL
  • dynamically retrieve a URL from a Sparkle feed
  • mount DMGs
  • stage, copy, delete files
  • import into Munki, providing additional makepkginfo options
  • build flat installer packages with specific permissions, ownerships
  • extract version information, read/write/merge plists

Sometimes vendors make a stable URL available that always points to the latest version, for example Google Chrome. In other cases, a vendor may have written their own system to parse their own metadata feed structure, such as Bare Bones Software. In cases like the latter, it is almost always necessary to write a custom processor. There are also a number of processors in which HTML is scraped using a RegEx match for a predictable URL pattern (see Mozilla, Oracle Java 7, Puppet Labs).

Custom processors are written in Python. There is not yet documentation for writing your own, but hopefully these examples can get you started.

Separating recipe tasks

A number of the recipes in the AutoPkg recipes repo have both .munki and .pkg variants. Because both recipes need to first download the software that's going to be later processed, it's possible to define the download steps in one place as a "parent recipe", by setting the identifier of the parent recipe in the ParentRecipe top-level key in the recipe. The parent recipe's steps will run before the child recipe's.

An example of some recipes that break these tasks into a longer chain is the Adobe Flash Player recipes. Notice how the AdobeFlashPlayerRepackage.munki.recipe is a child recipe of the repackaging recipe, which is a child of the download recipe. The Flash Player recipes are also a good example of how a packaging recipe can do other things besides actually build packages, it can also simply copy them from one location to another, patch postinstall scripts, etc. Its output is always a pkg, however.

There's no rule that your recipe must do this if you only plan to ever use it with Munki, but by separating this up front you make it easier should you or anyone else wish to add another variant to the recipe (for example, importing into some other software management system).

Identifiers

It's very important to decide on a unique identifier for the recipe that will remain fixed. The reverse-domain naming style should contain:

  • home of the repo (probably usually com.github.)
  • maintainer/org name (ie. a GitHub user name, Google Code project, etc.)
  • what the recipe does (ie. .download, .pkg, .munki)
  • the actual name of the software

For example: com.github.foo.pkg.app - written by user "foo", builds a pkg of "app"

Input variables

Your recipe may support additional parameters for pulling alternate versions, branches, languages, etc, and can do so via input variables. At other points in the recipe these values can be substituted in via enclosing % characters. For example, the Firefox.download recipe supports LOCALE and RELEASE input variables. You'll notice these are simply passed as arguments to the MozillaURLProvider processor.

Any custom input variables you support in the recipe should be clearly documented in the Description key.

Assuming you are sharing your recipe, consider these variable names to be your recipe's "API", because changing them will mean that the recipe will no longer be overridden as expected, for as long as a user is still overriding the old key name. The only time to change existing variable names might be for an entirely new recipe. Adding new variables to support new functionality in your recipe is ok, as long as existing functionality remains unchanged.

Versions

Sometimes a recipe may not be useful only for retrieving the latest update, but a specific previous version – especially if this version is a prerequisite to the latest update. For example, Office 2011 updates after 14.1.0 mostly require at least 14.1.0 to be installed first. Maybe you don't yet have this update in your repo and would like to get it the same way AutoPkg gets the latest updates. The recipe-specific processor included with the MSOffice2011Updates recipes makes use of the same metadata XML feed used by Microsoft's own Auto-Updater, and is therefore able to pull the same versions it exposes.

If your recipe is able to pull alternate versions, provide this capability with a VERSION Input variable, which defaults to latest.

If an intermediate update is required, it's possible to do a one-off override of VERSION with the -k/--key option:

autopkg run -k VERSION=14.1.0 MSOffice2011Updates.munki

For examples on how this is done in recipe-specific processors, the processors used for Office 2011 and Adobe Acrobat recipes are a good place to look.

Table of Contents

Clone this wiki locally