My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
PkginfoFiles  
Details on the format of pkginfo files
Updated Feb 15, 2012 by Nate.Wa...@gmail.com

Introduction

Much (most?) of the stuff munki can do is because of the package metadata made available through the catalogs, which are in turn made from data in pkginfo files. Pkginfo files can be generated with the makepkginfo tool. Though some of this info can be gleaned from the packages themselves, admins can and should add additional information (and sometimes correct the autogenerated info!).

See SupportedPkginfoKeys for an exhaustive list of valid pkginfo keys.

Details

Here's an example pkginfo file:

<?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>name</key>
	<string>ServerAdministrationSoftware</string>
	<key>version</key>
	<string>10.5.5</string>
	<key>description</key>
	<string>Administration tools for OS X Server</string>
	<key>display_name</key>
	<string>Server Administration Software</string>
	<key>installs</key>
	<array>
		<dict>
			<key>type</key>
			<string>application</string>
			<key>path</key>
			<string>/Applications/Server/Server Admin.app</string>
			<key>CFBundleIdentifier</key>
			<string>com.apple.ServerAdmin</string>
			<key>CFBundleName</key>
			<string>Server Admin</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.3</string>
		</dict>
		<dict>
			<key>type</key>
			<string>application</string>
			<key>path</key>
			<string>/Applications/Server/Workgroup Manager.app</string>
			<key>CFBundleIdentifier</key>
			<string>com.apple.WorkgroupManager</string>
			<key>CFBundleName</key>
			<string>Workgroup Manager</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.5</string>
		</dict>
	</array>
	<key>receipts</key>
	<array>
		<dict>
			<key>packageid</key>
			<string>com.apple.pkg.ServerAdminTools</string>
			<key>version</key>
			<string>10.5.3.0</string>
		</dict>
		<dict>
			<key>packageid</key>
			<string>com.apple.pkg.ServerSetup</string>
			<key>version</key>
			<string>10.5.3.0</string>
		</dict>
	</array>
	<key>minimum_os_version</key>
	<string>10.5.0</string>
	<key>installer_item_location</key>
	<string>apps/ServerAdminToold1055.dmg</string>
	<key>uninstallable</key>
	<true/>
	<key>uninstall_method</key>
	<string>removepackages</string>
</dict>
</plist>

Let's tear it apart:

<dict>
	<key>name</key>
	<string>ServerAdministrationSoftware</string>
	<key>version</key>
	<string>10.5.5</string>
	<key>description</key>
	<string>Administration tools for OS X Server</string>
	<key>display_name</key>
	<string>Server Administration Software</string>

name, version, and description should be easy to understand. display_name is an optional key, used to provide a "pretty" display name in the ManagedSoftwareUpdate app.

	<key>installs</key>
	<array>
		<dict>
			<key>type</key>
			<string>application</string>
			<key>path</key>
			<string>/Applications/Server/Server Admin.app</string>
			<key>CFBundleIdentifier</key>
			<string>com.apple.ServerAdmin</string>
			<key>CFBundleName</key>
			<string>Server Admin</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.3</string>
		</dict>
		<dict>
			<key>type</key>
			<string>application</string>
			<key>path</key>
			<string>/Applications/Server/Workgroup Manager.app</string>
			<key>CFBundleIdentifier</key>
			<string>com.apple.WorkgroupManager</string>
			<key>CFBundleName</key>
			<string>Workgroup Manager</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.5</string>
		</dict>
	</array>

The (optional) installs key is interesting. This must be created by the administrator. It is a list of dictionaries; each dictionary item describes something that is installed by the installation package. Currently supported items:

application

		<dict>
			<key>type</key>
			<string>application</string>
			<key>path</key>
			<string>/Applications/Server/Workgroup Manager.app</string>
			<key>CFBundleName</key>
			<string>Workgroup Manager</string>
			<key>CFBundleIdentifier</key>
			<string>com.apple.WorkgroupManager</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.5</string>
                        <key>minimum_update_version</key>
                        <string>1.0</string>
		</dict>

First, installcheck looks at the specified path for the application. If it doesn't find it there, system_profiler is used to look for an application matching the CFBundleName or CFBundleIdentifier; the version is compared to CFBundleShortVersionString. All of these values can be found in an application's Contents/Info.plist.

If (optional) minimum_update_version is supplied, only installed versions of the app of version # >= minimum_update_version will be matched.

bundle

		<dict>
			<key>type</key>
			<string>bundle</string>
			<key>path</key>
			<string>/Applications/Server/Server Assistant.app/Contents/Plug-ins/BackupServer.bundle</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.1</string>
                        <key>minimum_update_version</key>
                        <string>1.0</string>
		</dict>

A more generic bundle comparison, this time found by path. If the bundle is found at the given path, the CFBundleShortVersionString is compared with the CFBundleShortVersionString in bundle's Contents/Info.plist.

Once again, if (optional) minimum_update_version is supplied, only installed versions of the bundle of version # >= minimum_update_version will be matched.

plist

		<dict>
			<key>type</key>
			<string>plist</string>
			<key>path</key>
			<string>/Applications/Server/Server Admin.app/Contents/Info.plist</string>
			<key>CFBundleShortVersionString</key>
			<string>10.5.3</string>
		</dict>

A generic plist comparison which might be useful for Info.plists or version.plists in odd locations.

file

		<dict>
			<key>type</key>
			<string>file</string>
			<key>path</key>
			<string>/var/db/b.receiptdb</string>
			<key>md5checksum</key>
			<string>375bb4dca4624474019338a5c1246f82</string>
                </dict>

The attribute path is checked for existence. If the key md5checksum exists, the checksum of the file on disk is compared with the provided checksum.

The easiest way to create the installs item keys is using the makepkginfo tool, and providing paths to the items:

makepkginfo /path/to/TextWrangler.pkg.dmg -f /Applications/TextWrangler.app

Back to the original catalogitem:

	<key>receipts</key>
	<array>
		<dict>
			<key>packageid</key>
			<string>com.apple.pkg.ServerAdminTools</string>
			<key>version</key>
			<string>10.5.3.0</string>
		</dict>
		<dict>
			<key>packageid</key>
			<string>com.apple.pkg.ServerSetup</string>
			<key>version</key>
			<string>10.5.3.0</string>
		</dict>
	</array>

receipts is a list of packageids installed by the installer item. The makepkginfo tool does its best to figure out what packageids are in a given installer item.

receipts are used two ways:

  1. If there is no installs key, catalogcheck uses the receipts list to determine if a given item is installed or not.
  2. If the package is marked as uninstallable and the uninstall method is removepackages, this is the list of packages to remove.

Returning to the catalogitem:

	<key>minimum_os_version</key>
	<string>10.5.0</string>

When managedsoftwareupdate is looking for valid items to install, it checks the OS version of the current machine against this key. installitems that require a later OS version than the OS on the current machine are skipped. Note this can cause errors in the log if a manifest refers to "MyGreatApp" for a machine, but all the pkginfo items for various versions of "MyGreatApp" require a later version of the OS than the current machine. managedsoftwareinstall will complain that it cannot find info for MyGreatApp.

maximum_os_version can also be specified, using the same format as minimum_os_version.

	<key>installer_item_location</key>
	<string>apps/ServerAdminToold1055.dmg</string>

This is the relative path to the installer item on the repo webserver.

	<key>uninstallable</key>
	<true/>
	<key>uninstall_method</key>
	<string>removepackages</string>
</dict>
</plist>

These optional keys determine if ManagedInstaller can attempt to uninstall this item. The two supported uninstall_methods are removepackages and a full path to an executable script that does the uninstall, for example from the catalogitem for XcodeTools:

	<key>uninstallable</key>
	<true/>
	<key>uninstall_method</key>
	<string>/Developer/Library/uninstall-devtools</string>

Additional keys not shown in the example

Optional dependencies/relationship keys

There are two kinds of dependency/relationship keys, which define how various install items are related to each other.

requires

requires are prerequisites: package B requires package A be installed first. if package B is removed, package A is unaffected.

The requires key has an array as its value, as a given item could require multiple items to be installed first.

    <key>requires</key>
    <array>
	  <string>XcodeTools</string>
    </array>

With requires, if you remove an item A that is required by an item B, both A and B will be removed, since presumably B will be broken without A. An example: let's say you have a Photoshop plugin. It requires that Photoshop be installed in order to operate, so it specifies Photoshop in its requires attribute. Later you remove Photoshop, managedsoftwareupdate sees that there is a plugin installed that requires Photoshop, so it removes the plugin as well.

No checking is done for circular dependencies - so don't make any.

    <key>requires</key>
    <array>
	  <string>XcodeTools</string>
    </array>

If the above dependencies key was included in the pkginfo for ServerAdminTools, it would ensure that XcodeTools was installed before installing ServerAdminTools. On removal, if you tried to remove XcodeTools, ServerAdminTools would also be removed.

update_for

This is also a list of other pkginfo items. When processing managed_installs, munki looks at each item in turn. When considering item 'A', if it is installed, or scheduled to be installed, munki looks through the available catalogs, looking for other items that declare that they are updates for 'A'. If it finds any, and they are not currently installed, it adds them to the install list.

This provides a mechanism for munki to automatically discover new updates for items without the admin having to edit existing manifest files.

Some examples:

	<key>name</key>
	<string>PhotoshopCameraRaw</string>
	<key>version</key>
	<string>5.5.0.0.0</string>
	<key>update_for</key>
	<array>
	  <string>PhotoshopCS4</string>
	  <string>AdobeCS4DesignStandard</string>
	</array>

and

	<key>name</key>
	<string>iWork09_Update</string>
	<key>version</key>
	<string>4.0.3.0.0</string>
	<key>requires</key>
	<array>
	  <string>iWork09_Update-4.0.2.0.0</string>
	</array>
	<key>update_for</key>
	<array>
	  <string>iWork09</string>
	</array>

Note that you would not use this for new versions of a package - these would simply have the same name as the older package, but a higher version number. But some (much?) commercial software packages its updates as updaters or "patches", in which the new package is added to the existing package, instead of replacing it. The update_for key identifies these and provides the "parent" packages they update.

Note also this construction:

<string>iWork09_Update-4.0.2.0.0</string>

This tells munki to look for a specific version (in this case '4.0.2.0.0') of 'iWork09_Update'. Without the version extension, munki always uses the most recent (or "highest") version it can find in the catalogs that are available. You can use this construction anywhere you'd refer to a package, including in the managed_installs key of a manifest.

When processing removals, if item 'A' is scheduled to be removed, any item that declares it is an update for 'A' is also scheduled for removal if it is installed.

More optional keys

	<key>installed_size</key>
	<integer>198356</integer>
	<key>installer_item_size</key>
	<integer>588922</integer>

updatecheck uses these to determine if there is enough free space to download the installer item and install it.

supported_architectures

You can specify which architectures a pkg is compatible with:

PowerPC only:

	<key>supported_architectures</key>
	<array>
		<string>Power Macintosh</string>
	</array>

Intel Only (Both 32bit and 64bit) :

	<key>supported_architectures</key>
	<array>
		<string>i386</string>
		<string>x86_64</string>
	</array>

RestartAction

You may specify which type of Restart you would prefer for a given package:

Shutdown

<key>RestartAction</key>
<string>RequireShutdown</string>

Restart

<key>RestartAction</key>
<string>RequireRestart</string>

Logout

<key>RestartAction</key>
<string>RequireLogout</string>

Embedded uninstall scripts

You may embed uninstall scripts directly into the pkginfo item:

	<key>uninstall_method</key>
	<string>uninstall_script</string>
	<key>uninstall_script</key>
	<string>#!/bin/sh

rm -rf "/Applications/Adobe Reader.app"
rm -rf "/Library/Internet Plug-ins/AdobePDFViewer.plugin"
rm -f "/Library/Application Support/Adobe/HelpCfg/en_US/Reader_10.0.helpcfg"

pkgutil --forget com.adobe.acrobat.reader.10.reader.app.pkg.en_US
pkgutil --forget com.adobe.acrobat.reader.10.reader.browser.pkg.en_US
pkgutil --forget com.adobe.acrobat.reader.10.reader.appsupport.pkg.en_US
	</string>
	<key>uninstallable</key>
	<true/>

preinstall_script/postinstall_script

As of SVN r1061:

pkginfo items can now optionally contain a preinstall_script and/or a postinstall_script. These are embedded shell scripts that are similar to the optional embedded uninstall_script.

These are executed as root. Assume nothing about the environment, including command paths.

Failure of the preinstall_script will abort the installation attempt. Failure of the postinstall_script will log errors, but the install will be considered complete.

preuninstall_script/postuninstall_script

As of SVN r1194:

pkginfo items can now optionally contain a preuninstall_script and/or a postuninstall_script. These are embedded shell scripts that are similar to the optional embedded uninstall_script.

These are executed as root. Assume nothing about the environment, including command paths.

Failure of the preuninstall_script will abort the removal attempt. Failure of the postuninstall_script will log errors, but the removal will be considered complete.

Unattended Installs and Uninstalls

This feature is available as of SVN r814.

Using an additional key in the pkginfo file, admins can designate installs/updates or uninstalls to occur silently and unattended before the user is notified of any remaining installs/updates/removals. This feature is very raw and should be used wisely only with packages the admin has thoroughly tested; given that this feature suppresses all notification to the user, installs may occur while the user is running the application being updated or removed. Unattended installs/uninstalls are executed in the background immediately after being downloaded, regardless if the user has been notified or not on the given day, only when managedsoftwareupdate is called with --auto (which is how launchd executes managedsoftwareupdate regularly).

unattended_install takes effect for managed_installs and managed_updates Manifests install types, and unattended_uninstalls for managed_uninstalls.

Below is an example of the unattended pkginfo keys, where the install would not be unattended (the user will be notified as normal), and the uninstall is unattended (package will be uninstalled in the background).

	<key>unattended_install</key>
	<false/>
	<key>unattended_uninstall</key>
	<true/>

Note: this is an optional key, to setting to false is the same as omitting the key altogether.

Note: SVN r1098 renamed forced_install/forced_uninstall to unattended_install/unattended_uninstall respectively. Munki clients of version 0.7.0 and before should use the forced_(un)install naming, and clients 0.7.1 and later should use the unattended_(un)install naming. During migration from 0.7.0 to 0.7.1, you may want to include both forced and unattended keys in your pkginfo files to ensure desired aggressiveness on old and new clients alike.

Force Install After Date

This feature is available as of SVN r1270

Using an additional key in the pkginfo file, admins can designate installs/updates to forcefully logout and/or restart a machine in order to install a package requiring such. Given that this feature has the potential to forcefully restart a machine while a user is performing work or has unsaved work open, it should be used wisely and and admins should provide sufficient notice to their users. We recommend setting force datetimes at least 2 weeks in the future.

Package Info Key

The pkginfo key, force_install_after_date, is a date value expressed in the following format: yyyy-dd-hhThh:mm:ssZ. For example, August 3rd 2011 at 1PM is the following: <date>2011-08-03T13:00:00Z</date> The date specified here is evaluated in local time, so all timezone specific information is stripped and ignored. In the example above, clients will forcefully logout and perform the install at 1PM based on whatever the local time of the client machine is.

If you need an install/update requiring a logout/reboot to be forced as soon as possible, specific a date in the past. Do note that this may be highly disruptive to your users, though.

Notifications

Packages that have a force_install_after_date set will show up with an exclamation point in the Managed Software Update GUI. When highlighting the application in the list, the description is appended with more detail about the force install.

Starting at 72 hours before the force datetime, when Later is clicked in the MSU update window, a message will be presented warning the user of the impending force install. The MSU GUI will still only display based on the ManagedInstalls::DaysBetweenNotifications setting, which defaults to once per day.

Starting at 240 minutes (4 hours) before the force datetime, the MSU GUI will be displayed with a more intrusive warning notification. This notification will be displayed at 240, 180, 120, 90, 60, 45, 30, 15, 10, and 5 minutes. A final notification will also be displayed roughly 1 minute before force logout/restart.

Minimum Notification

If a machine is powered off or asleep while a force install is due to take place, it will start at 60 minutes worth of notifications. If the machine then is put asleep until that new 60 minute counter has been started, the machine will perform the force install within minutes of waking up.

installer_environment

New for 0.8.2 Build 1425:

This key allows the admin to specify arbitrary environment variables for use by /usr/sbin/installer.

Some (broken) packages and pre/post script that only do the right thing if /usr/bin/installer's environment is that of the current console user. Since Munki runs as root, this is not the case when Munki installs items.

You may be able to work around broken pre/postinstall scripts that reference the current username or user home by specifying the correct values in an installer_environment dictionary.

Here's the most common implementation:

<key>installer_environment</key> 
<dict> 
    <key>USER</key> 
    <string>CURRENT_CONSOLE_USER</string> 
</dict>

Which causes Munki to substitute the current console user name (or root if there is none). Alternately, you could specify a known-to-exist local user:

<key>installer_environment</key> 
<dict> 
    <key>USER</key> 
    <string>localstudentuser</string> 
</dict>
Comment by leefromp...@gmail.com, Nov 17, 2011

I just recently started using 'restart required' in a few pkginfos, and noticed there wasn't much documentation on here. I learnt about it via an old bug report on here, so for those interested in forcing a restart after a pkg install (even if the .pkg itself doesn't dictate a restart being necessary), simply insert into your pkginfo:

<key>RestartAction</key>
<string>PREFERRED OPTION</string>

replacing the preferred option string with one and only one of the following;

<string>RequireShutdown</string>
<string>RequireRestart</string>
<string>RequireLogout</string>.

-Lee

Comment by wiseb...@gmail.com, Dec 15, 2011

Thanks Lee, that's exactly what I was looking for. We are using Thursby ADmitMac for SmartCard? login and if updates install without a restart/reboot then users are not able to login anymore. Thursby's ADmitMac is very very very sensitive not very robust.


Sign in to add a comment
Powered by Google Project Hosting