Flat Package Format - The missing documentation

Description


This document will try to document the Flat Package Format introduced by Apple in Mac OS X 10.5. Please keep in mind, this is built from reverse-engineering the format so it may contain inaccuracies for options that are both undocumented and kept secret by Apple.

The world is flat, deal with it.


With previous versions of Mac OS X, a package was a Mac OS X bundle that contains a payload, scripts and a description of the package requirements and behavior. This type of package is still supported in Mac OS X 10.5 but a new format of package was introduced: flat packages.

Flat packages are called that way supposedly because the package is now just a file. This file is actually a xar archive.

You can inspect the contents of a flat package 3 ways:

A flat package can describe either a metapackage or a single package. We won't discuss metapackage in this document for the time being. Here are 3 examples of flat packages:

A minimal flat packageA flat package with scriptsA Leopard update package


As can be seen on these pictures, a flat package can contains 5 different files:

NameRequiredDescription
PackageInfoYesThis is a XML document that contains information about the package behavior and requirements.
BomYesThis is the Bill of Materials for the files contained in the Payload archive. See mkbom (8).
PayloadYesThis is an archive of the hierarchy of files to be installed. The hierarchy is saved as cpio archive compressed with gzip (or, recently, compressed as a concatenation of LZMA chunks). See cpio(1), ditto(1), gzip(1).
ScriptsOptionalThis is an archive of scripts and additional resources. The hierarchy is saved as cpio archive compressed with gzip. See cpio(1), ditto(1), gzip(1). This file is optional.
RunAtStartupOptionalThis is a shell script that will be supposedly invoked on the next Mac OS X startup.

PackageInfo


The PackageInfo file is a XML document that provides information about the package behavior, requirements and identity.

A PackageInfo skeleton looks like this:

<?xml version="1.0"?>
<pkg-info>
    <deferred-install>
        ...
    </deferred-install>
    <payload/>
    <dont-obsolete>
        ...
    </dont-obsolete>
    <patch>
        ...
    </patch>
    <scripts>
        ...
    </scripts>
    <groups>
        ...
    </groups>
    <install-at-startup>
        ...
    </install-at-startup>
    <relocate>
        ...
    </relocate>
    <locator>
        ...
    </locator>
    <bundle/>
    ...
    <bundle-version>
        ...
    </bundle-version>
</pkg-info>


The different elements are the following ones:

ElementRequiredPackageMaker SupportDescription
pkg-infoYesPartialThis element provides information about the authentication requirements, the package behavior after installation succeeded, etc.
deferred-installOptionalNoThis element provides information about files that should be installed after reboot.
payloadYesYesThis element provides information on the number of files in the payload and the size of the payload.
dont-obsoleteOptional?Description Forthcoming
patchOptionalYesThis element provides information about the files that should be patched.
scriptsOptionalYesThe children of this element describe what scripts to run before and after installation.
groupsOptionalNoThis is used by Apple. Description forthcoming.
install-at-startupOptionalNoThe children of this element describe which files are to be installed on the next Mac OS X startup.
relocateOptionalYesDescription Forthcoming.
locatorOptionalYesDescription Forthcoming.
bundleOptionalYesThese elements provide versioning information about bundles within the payload.
bundle-versionOptionalYesThe children of this element define a list of bundles that can not be downgraded during the installation.

Note: The <?xml version="1.0"?> element is not created by PackageMaker. From a XML point of view, it's probably a bug but yet it still works without it.


pkg-info

The pkg-info element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
format-versionYesYes2Defines the format version for the package.
identifierYesYesUniform Type Identifier StringDefines the package identifier. It should ideally be unique for the package.
authYesYesnone
root
Defines if the user needs to authenticate as an admin user to install the package.
versionYesYesVersion StringDefines the version of the package. The version of the package is specific to your package and should not be related to the version of the applications you install if possible.
install-locationOptionalYesUnix file pathDefines the default location where the payload hierarchy should be installed.
relocatableOptionalYestrue
false
Description forthcoming.
postinstall-actionOptionalYeslogout
restart
shutdown
Defines the action to perform after a successful installation.
deleteObsoleteLanguagesOptionalNotrue
false
Description forthcoming.
overwrite-permissionsOptionalNotrue
false
Defines if the permissions of existing directories should be updated with the ones of the same directories within the payload archive.
followSymLinksOptionalNotrue
false
Defines if when Installer finds a symbolic link when installing files, the link should be resolved instead of being replaced by a real file or folder.
useHFSPlusCompressionOptionalNotrue
false
Define if the items in the package should be compressed after installation. Not supported on Mac OS X 10.5.
minimumSystemVersionOptionalNoVersion stringProbably defines the minimum OS version on which the package can be installed. Not supported/used by Mac OS X 10.5.
preserve-xattrOptionalNotrue
false
Description forthcoming.


payload

The payload element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
installKBytesYesYesIntegerDefines the size in Kilobytes of the payload uncompressed.
numberOfFilesYesYesIntegerDefines the number of files and folders inside the payload.
external-rootNoNoAbsolute Unix File PathDefines the location of the external payload folder. If defined, the "Payload" file should not be included in the flat package but the "Bom" file is required. This is supported on Mac OS X 10.7 or later.


dont-obsolete

?. You can have multiple instances of the file element. Here is an example:

    <dont-obsolete>
        <file path="/usr/bin/gnutar"/>
        <file path="/usr/bin/tar"/>
    </dont-obsolete>

File elements of the dont-obsolete element use the following attribute: path.


patch

The patch section contains a list of files to be patched. You can have multiple instances of the file element. Here is an example:

    <patch>
        <file required-sha1="88612578d147f58d5daa6e0aed373d1e1c934e6c" sha1="88612578d147f58d5daa6e0aed373d1e1c934e6c" path="./01example-contents.xml"/>
        <file required-sha1="a21d689dddaf3aa3b73d8108c61af77d681ac1f6" sha1="a21d689dddaf3aa3b73d8108c61af77d681ac1f6" path="./01example.xml"/>
    </patch>

File elements of the patch element use the following attributes: required-sha1, sha1,and path.


scripts

The scripts section contains a list of scripts to be executed before or after installation. You can have multiple instances of the preinstall or postinstall elements. Here is an example:

    <scripts>
        <preinstall file="./preinstall"/>
        <postinstall file="./postinstall"/>
    </scripts>


preinstall

The preinstall element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
fileYesYesUnix relative file pathDefines the relative path to the pre-installation script. ./ represents the first level of the file hierarchy archived in the Scripts file. This script will be run after the files installation.
component-idOptionalYesUniform Type Identifier stringDefines the id of a bundle element. The script will be run before the bundle is installed.


postinstall

The postinstall element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
fileYesYesUnix relative file pathDefines the relative path to the pre-installation script. ./ represents the first level of the file hierarchy archived in the Scripts file. This script will be run after the installation succeeded.
component-idOptionalYesUniform Type Identifier stringDefines the id of a bundle element. The script will be run before the bundle is installed.


groups

Description forthcoming.


install-at-startup

The install-at-startup section contains a list of files that should be installed on the next startup of the Mac. This works in collaboration with the RunAtStartup script. You can have multiple instances of the file element. Here is an example from the Mac OS X 10.5.6 updater:

    <install-at-startup>
        <file path="/usr/libexec/oah/translate"/>
        <file path="/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CodeResources"/>
        <file path="/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics"/>
        ...
    </install-at-startup>

File elements of the dont-obsolete element use the following attribute: path.


relocate

The relocate element associates a search-id with one (or more) bundle. Here is an example:

    <relocate search-id="whereisit">
        <bundle id="/Applications/Ivanhoe.app"/>
    </relocate>

The relocate element can have the following attribute:

AttributeRequiredPackageMaker SupportValuesDescription
search-idYesYesStringIdentifier of the search element used to find the instances of the bundle(s).

Bundle elements of the relocate element can use the following attribute: CFBundleIdentifier, CFBundleVersion, CFBundleIdentifier, CFBundleShortVersionString, SourceVersion, path or id.


locator

The locator section contains a list of searches used to locate the instances of specified bundles on disk. Here is an example:

    <locator>
        <search type="component" id="CommonSearchPath">
            <bundle CFBundleIdentifier="fr.whitebox.Ivanhoe" path="/Applications/Ivanhoe.app">
        </search>
        <search type="script" id="whereisit" script="findme()">
            <script>
                function findme()
                {
                    return my.search.results['CommonSearchPath'];
                }
            </script>
        </search>
    </locator>


search

Description Forthcoming



bundle-version

The bundle-version section contains the list of bundles that can not be downgraded by the installation process. Here is an example:

    <bundle-version>
        <bundle id="com.CRYPTOCard.SmartcardReader"/>
        <bundle id="com.CRYPTOCard.iokit.SmartCardReader"/>
        ...
    </bundle-version>

Bundle elements of the bundle-version element can use the following attribute: CFBundleIdentifier, CFBundleVersion, CFBundleIdentifier, CFBundleShortVersionString, SourceVersion, path or id.

Common element types


Some element types are used as children of other elements. The attributes used for these elements may wary depending on the parent element.


bundle

A bundle element can include other bundle elements. Once a bundle has been defined, it can be referenced using its id attribute elsewhere. The bundle element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
CFBundleIdentifier-YesStringUniform Type Identifier of the bundle. See Runtime Configuration Guidelines for more information.
CFBundleVersion-NoStringBuild version number of the bundle. This is retrieved from the Info.plist file of the bundle. See Runtime Configuration Guidelines for more information.
CFBundleShortVersionString-NoStringRelease version of the bundle. This is retrieved from the Info.plist file of the bundle. See Runtime Configuration Guidelines for more information.
SourceVersion-?Unix file pathDescription forthcoming
id-YesUniform Type Identifier StringThis is the identifier for the bundle. It should be a Uniform Type Identifier. It usually is the CFBundleIdentifier value of the bundle.
path-YesUnix file pathThis is the path of the bundle inside the payload. If the bundle element is a child of another bundle element. The path is a relative path to the parent bundle.


file

The file element can have the following attributes:

AttributeRequiredPackageMaker SupportValuesDescription
path-YesUnix file pathDescription forthcoming
required-sha1-YesSHA1 SignatureSignature of the file that should be patched.
sha1-YesSHA1 SignatureDescription forthcoming.





Document Revision History

DateNotes
2016-08-22Added entry for the preserve-xattr attribute.
2016-02-22Added description for the external-root attribute.
Added note about the new LZMA compression.
2009-12-19Added description for the deferred-install element and useHFSPlusCompression attribute.
Fix the sample for the search script sample.
Re-organize a bit the elements.
2009-03-31Added description for the locator and relocate elements.
2009-03-16Added description for the followSymLinks attribute.
2009-03-12Added the dont-obsolete element and fixed a typo.
2009-02-28Fixed the description of the bundle-version element.
2009-02-19Added description for the patch and file elements.
2009-01-25Added description for the bundle-id attribute.
2009-01-21Fixed a mistake regarding PackageMaker component-id support.
Added descriptions regarding bundle elements.
2008-12-31Added some information about the bundle-version section.
Added the relocate and locator sections.
2008-12-24Added the Scripts section.
Added the note on the xml tag.
Begun work on the install-at-startup section.
2008-12-23First draft