Signs of Triviality

Opinions, mostly my own, on the importance of being and other things.
[homepage] [index] [jschauma@netmeister.org] [@jschauma] [RSS]

Creating an OS X .pkg installer

June 22nd, 2013

After pushing a few more people to use jass(1) to easily encrypt data using SSH keys, I wanted to provide an OS X installer for it. Unfortunately, I wasn't able to find a reasonable explanation of how to build such a package. Some of the pages covering this topic pointed to an OS X developer tool called "Package Maker", which wasn't easy to actually find (it's not part of the gigantic XCode package, but rather part of the "Auxiliary Developer Tools" package).

Either way, Package Maker is a GUI application. I was looking for the commands to create the package, so I can stick them into my Makefile. So after looking at the output of running Package Maker and a few existing packages, I came up with the following:

Prepare a destination root
This directory will contain the files you want to install with their full path. In my case, this was basically:

export NAME=jass
mkdir -p dstroot/usr/local/bin dstroot/usr/local/share/man/man1
install -c -m 0755 src/${NAME} dstroot/usr/local/bin/${NAME}
install -c -m 0644 doc/${NAME}.1 dstroot/usr/local/share/man/man1/${NAME}.1
sudo chown -R root:staff dstroot

Prepare a package directory
An OS X pkg is just a directory, so create it and populate it with some metadata:

mkdir -p ${NAME}.pkg/Contents/Resources
install -c -m 644 README ${NAME}.pkg/Contents/Resources/ReadMe.txt
install -c -m 644 LICENSE ${NAME}.pkg/Contents/Resources/License.txt
echo -n pmkrpkg1 > ${NAME}.pkg/Contents/PkgInfo
cat > ${NAME}.pkg/Contents/Info.plist <<EOF
<?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>CFBundleIdentifier</key>
        <string>com.twitter.${NAME}.pkg</string>
        <key>CFBundleShortVersionString</key>
        <string>1.4</string>
        <key>IFMajorVersion</key>
        <integer>1</integer>
        <key>IFMinorVersion</key>
        <integer>4</integer>
        <key>IFPkgFlagAllowBackRev</key>
        <false/>
        <key>IFPkgFlagAuthorizationAction</key>
        <string>RootAuthorization</string>
        <key>IFPkgFlagDefaultLocation</key>
        <string>/</string>
        <key>IFPkgFlagFollowLinks</key>
        <true/>
        <key>IFPkgFlagInstallFat</key>
        <false/>
        <false/>
        <key>IFPkgFlagInstalledSize</key>
        <integer>20</integer>
        <key>IFPkgFlagIsRequired</key>
        <false/>
        <key>IFPkgFlagOverwritePermissions</key>
        <false/>
        <key>IFPkgFlagRelocatable</key>
        <false/>
        <key>IFPkgFlagRestartAction</key>
        <string>None</string>
        <key>IFPkgFlagRootVolumeOnly</key>
        <false/>
        <key>IFPkgFlagUpdateInstalledLanguages</key>
        <false/>
        <key>IFPkgFormatVersion</key>
        <real>0.10000000149011612</real>
</dict>
</plist>
EOF

Create a bill-of-materials file
Use mkbom(8) to create a bom(8) file to tell the installer which files need to be installed:

mkbom dstroot ${NAME}.pkg/Contents/Archive.bom

Create an archive of the files to install
It appears that a compressed cpio archive will do:

cd dstroot && pax -w -x cpio . -f ../${NAME}.pkg/Contents/Archive.pax
gzip ${NAME}.pkg/Contents/Archive.pax

Create a .dmg image
To allow users to download the installer, create a .dmg:

hdiutil create -volname ${NAME} -srcfolder ${NAME}.pkg -ov -format UDZO ${NAME}.dmg

And that's it. I've added all these commands to the jass Makefile, so I can now run make osxpkg and find a file jass.dmg ready to give to users to download. After mounting the .dmg file, you should find the familiar package logo, and if you open the installer, it should Do The Right Thing:

Now I'm sure there are many things you can do to customize or improve the installer, but it appears you actually do not need Package Maker or any other GUI tools, and if nothing else, hopefully these steps help you get started should you need to package something simple.

June 22nd, 2013


[Security Related Interview Questions for all Engineers] [Index] [One City One Book - Online Privacy Tools]