startosinstall tool in the High Sierra installer supports adding additional packages that will be installed after macOS is installed, via the
bash-3.2$ /Applications/Install\ macOS\ High\ Sierra.app/Contents/Resources/startosinstall --usage Usage: startosinstall Arguments --applicationpath, a path to copy of the OS installer application to start the install with. --license, prints the user license agreement only. --agreetolicense, agree to license the license you printed with --license. --rebootdelay, how long to delay the reboot at the end of preparing. This delay is in seconds and has a maximum of 300 (5 minutes). --pidtosignal, Specify a PID to which to send SIGUSR1 upon completion of the prepare phase. To bypass "rebootdelay" send SIGUSR1 back to startosinstall. --converttoapfs, specify either YES or NO on if you wish to convert to APFS. --installpackage, the path of a package to install after the OS installation is complete; this option can be specified multiple times. --usage, prints this message. Example: startosinstall --converttoapfs YES
A High Sierra NetInstall image built with System Image Utility has a similar option: you can add additional packages to the install:
Unfortunately, under both 10.13 and 10.13.1, both methods have a similar issue: if you try to install multiple packages, in some/many cases the installer will not properly cache all the intended packages and the install of macOS will fail with the message “The path /System/Installation/Packages/OSInstall.mpkg appears to be missing or damaged.” It tells you to restart and try again (which won’t work…).
Adding a single additional package does work reliably, so one workaround would be to build a single mega package that contains all the components you wish to have installed after macOS is installed.
It turns out there is another fix or workaround. I filed bugs with Apple on this issue, and got a response that I did not initially understand:
From: Apple Developer Relations
When you build your product archives, you should specify a unique product identifier e.g.
productbuild –distribution Distribution –identifier com.mycompany.pkg.uniqueid –version 1.0 product.pkg
You can verify that the product archive contains the product identifier by expanding the created product archive with pkgutil and opening the Distribution file – which should contain a tag e.g.
Initially I was quite frustrated by this response. I am always careful to set package identifiers for all packages I build and I was quite certain that all the packages I was trying to use had unique package identifiers.
It took a second set of eyes to clue me in that the response was referring not to package identifiers, but to something I’d never seen/noticed/knew about before: product identifiers. This is an optional bit of metadata that can be added to “product archives” or what is otherwise known as distribution-style packages.
I then tore apart many third-party and Apple distribution packages and found that while a few contained a product id in their Distribution file, many, maybe even most did not, including many distribution packages from Apple.
So I don’t know what inspired Apple developers to rely on this bit of data for the additional packages feature for macOS installs, but they did, and we (for now) must deal with that.
My munki-pkg project/tool (https://github.com/munki/munki-pkg) has been updated to add product id to component packages it builds, as have the build scripts for Munki (https://github.com/munki/munki/tree/master/code/tools). If you are building component packages yourself, you can use
productbuild to ensure a package has a product id:
productbuild --identifier com.myorg.uniqueid \ --package input_component.pkg output_distribution.pkg
If you have an existing component package that’s missing the product id, you can edit the Distribution file and add one. First you’d use
pkgutil to expand the component package:
pkgutil --expand some.pkg some_pkg
You’d then edit the Distribution file (yes, you can use a GUI editor if you prefer:
<?xml version="1.0" encoding="utf-8"?> <installer-gui-script minSpecVersion="1"> <pkg-ref id="com.foo.bar.pkg"> <bundle-version/> </pkg-ref> <options customize="never" require-scripts="false"/> <choices-outline> <line choice="default"> <line choice="com.foo.bar.pkg"/> </line> </choices-outline> <choice id="default"/> <choice id="com.foo.bar.pkg" visible="false"> <pkg-ref id="com.foo.bar.pkg"/> </choice> <pkg-ref id="com.foo.bar.pkg" version="1.0" onConclusion="none" installKBytes=“3">#FooBar.pkg</pkg-ref> </installer-gui-script>
<?xml version="1.0" encoding="utf-8"?> <installer-gui-script minSpecVersion="1"> <pkg-ref id="com.foo.bar.pkg"> <bundle-version/> </pkg-ref> <options customize="never" require-scripts="false"/> <choices-outline> <line choice="default"> <line choice="com.foo.bar.pkg"/> </line> </choices-outline> <choice id="default"/> <choice id="com.foo.bar.pkg" visible="false"> <pkg-ref id="com.foo.bar.pkg"/> </choice> <pkg-ref id="com.foo.bar.pkg" version="1.0" onConclusion="none" installKBytes=“3">#FooBar.pkg</pkg-ref> <product id="com.foo.bar.pkg" version="1.0"/> </installer-gui-script>
In case you missed it, I added
<product id="com.foo.bar.pkg" version="1.0"/>
near the end of the file, but before the “installer-gui-script” closing tag.
You would then flatten the expanded, modified package:
rm some.pkg pkgutil --flatten some_pkg some.pkg
NOTE: a significant side-effect of expanding and re-flattening a package like this is that is removes any package signing. Fortunately, the additional packages mechanism for the macOS High Sierra installer does not require signed packages.
In my testing, if all the additional packages in either the
startosinstall or NetInstall workflow have unique product ids, all packages are properly staged and will install after macOS is installed.