In previous posts, I demonstrated the basics of pre-commit and recommended its use for linting AutoPkg recipes. This time, I’ll discuss how pre-commit can be a lifesaver for those who use Munki to deploy software.
Setup
You’ll need a Munki repository tracked by Git. Setting up pre-commit in your Munki repo is simple:
-
Install pre-commit. I choose to do this with Homebrew:
brew install pre-commit
-
Create, commit, and push a .pre-commit-config.yaml file at the root of your Munki repository. To start, the contents of the file can be the following:
1 2 3 4 5
repos: - repo: https://github.com/homebysix/pre-commit-macadmin rev: v1.18.0 hooks: - id: check-munki-pkgsinfo
-
Activate the hooks in your Git repo:
cd /path/to/your_munki_repo pre-commit install
First I’ll cover what you get by adding the check-munki-pkgsinfo
hook, then I’ll show you how to customize it for your organization’s needs.
Check pkginfo files
The check-munki-pkgsinfo
hook includes many sanity checks that are generally applicable to Munki pkginfo files. Some of these checks are inherited from others’ Munki linting scripts, and others were born from my own past mistakes and learnings.
As of this writing, the check-munki-pkgsinfo
hook includes these checks:
-
The pkginfo file must be a valid plist.
-
The pkginfo must contain certain required keys. By default the required keys are
name
anddescription
. -
The key types must be what Munki expects. The list of pkginfo keys Munki supports is here; any keys that aren’t the expected type will produce an error.
-
No duplicate imports should be present in the repo. Duplicate imports are determined by the presence of a
__N
suffix (for example,Firefox-81.0.1__1.plist
). See below for information on how to make this a warning instead of an error. -
The values of certain keys must be valid. For example, the
RestartAction
key must be eitherRequireRestart
,RequireShutdown
, orRequireLogout
. Any other value will produce an error. -
Specific typos in key names will generate errors. For example,
minimum_os_vers
andmin_os_version
are both incorrect variations of the correct key,minimum_os_version
. -
Uninstall scripts must not be missing. If the pkginfo specifies an
uninstall_method
ofuninstall_script
, there must also be anuninstall_script
key with a script defined. -
Scripts must start with a shebang. You may optionally limit the shebang to a pre-approved list.
-
Paths in the
items_to_copy
list must omit trailing slashes. -
Icons used by pkginfo files must be present in the repository.
If any of these checks fail, you’ll be prevented from committing the file(s) using git commit
, as shown below.
% git commit -m "Add nopkg that triggers logout for FileVault" pkgsinfo/enable_filevault.plist
Check Munki Pkginfo Files................................................Failed
- hook id: check-munki-pkgsinfo
- exit code: 1
pkgsinfo/enable_filevault.plist: RestartAction key set to unexpected value: RequiredLogout
Once you’ve corrected the error, git commit
will succeed as usual.
% git commit -m "Add nopkg that triggers logout for FileVault" pkgsinfo/enable_filevault.plist
Check Munki Pkginfo Files................................................Passed
[master (root-commit) c4ebfb8] Add nopkg that triggers logout for FileVault
1 file changed, 62 insertions(+)
create mode 100644 pkgsinfo/enable_filevault.plist
Customizing pkginfo checks
Although the basic checks above may be good enough for many organizations, customization is available if you’d like to fine-tune or personalize the checks.
In general, pre-commit hooks are customized by passing a list of arguments. These command-line arguments relay additional information to the check function.
Any valid yaml array will work for args
. Three examples are shown below:
|
|
Tip: Quoting strings
I’ve chosen to quote all the examples on this page, because although YAML allows unquoted strings, it’s difficult to troubleshoot errors resulting from bad quoting. Save yourself some time and quote by default.
Tip: Ending arguments
When including an args
list with multi-value arguments, it’s a good idea to ensure the final item in the array is --
. This separator tells the command-line interpreter that the list of custom arguments are complete. You’ll see this separator used in all the examples in this post that have multi-part arguments.
Customizing required keys
If you want to specify pkginfo keys that should be required in addition to name
and description
, you can use the --required-keys
argument, as shown here:
|
|
Blocking applications for packages
If a blocking_applications
array doesn’t exist for a dmg installer, Munki determines the proper blocking apps to use based on the installs
array. However many pkg installers only use a receipts
array, not an installs
array, so you may wish to require a blocking_applications
array for pkg installers using this argument:
|
|
Note that an empty <array/>
will satisfy this requirement, which Munki treats the same as if there is no blocking_applications
key at all, for pkg installers.
Missing icon warnings
By default, icons referenced by pkginfo files that are absent from your repository will generate errors. If you wish to ignore these errors, the following option will make them non-failing warnings instead:
|
|
Duplicate import warnings
By default, files with the presence of a __N
suffix (for example, Firefox-81.0.1__1.plist
) in your repository will generate errors. However these may not actually be duplicates — perhaps they have different supported_architectures
or other keys. If you wish to ignore these errors, the following option will make them non-failing warnings instead:
|
|
Allowed catalogs and categories
Checking for specific allowable catalogs and categories is not enabled by default, but you can enable this check in your .pre-commit-config.yaml file using the following arguments:
|
|
Valid shebangs
Scripts in Munki pkginfo files require a shebang in the first line in order to ensure they are interpreted by the proper scripting runtime. If you choose, you can define a pre-approved set of shebangs that you expect all scripts in your repo to use. Any shebangs not in this list will result in an error.
|
|
Combining arguments
When combining arguments, just ensure the --
argument is the last one in the list. A working .pre-commit-config.yaml file that includes multiple of the above customizations may look like this:
|
|
Check MunkiAdmin scripts
If you use MunkiAdmin, you may be excited to learn of its presave/postsave scripts feature, which can run scripts before or after saving files in your repository. The check-munkiadmin-scripts
hook can be used to validate these scripts. This hook ensures that the scripts are executable and named properly.
Here’s how you can add the check-munkiadmin-scripts
hook to your .pre-commit-config.yaml file:
|
|
Rebuild Munki catalogs
This last hook runs the makecatalogs
command to ensure all referenced packages are present and catalogs are freshly built.
|
|
Other helpful hooks
Many of the helpful hooks mentioned in my previous post about linting AutoPkg recipes are equally useful for Munki repos. Review the list here.
Conclusion
By integrating pre-commit hooks into your Munki repository, your client platform engineering team can ensure that your pkginfo files and MunkiAdmin scripts are consistently validated and free of common errors. This not only helps maintain the integrity of your repository but also saves time and reduces the risk of deployment issues.
You can inspect the code that drives the check-munki-pkgsinfo
, check-munkiadmin-scripts
, and munki-makecatalogs
hooks on GitHub. If you have any questions or suggestions, I welcome issues and pull requests on the pre-commit-macadmin repository.