Oct 25, '05 06:30:00AM • Contributed by: dotgray
- Make a copy of the installer package (.pkg) file. If you downloaded the update as a .dmg file, just copy it to your Desktop.
- Right- or control-click on the package file and select "Show Package Contents" from the contextual menu, and navigate into the Contents folder.
- Open the .dist file in a straight-text editor (e.g. BBEdit, TextWrangler). The file will be named based on the package name, so for the DVDPlayerUpdate.pkg file, it's DVDPlayerUpdate.dist.
- Find the function volumeCheck(){ section, and comment out the following code using standard HTML comment tags, as seen here:
Save the file, close the package, and run the installer.<-- if(my.target.mountpoint != '/'){ my.result.message = system.localizedString('ERROR_BOOTVOL'); my.result.type = 'Fatal'; return false; } -->
[robg adds: I can't necessarily endorse running updates on non-boot volumes, but neither do I have evidence that it causes problems. As with many things on this site, proceed with care. Read on for more info on different variations, as well as the back story on how the author found this fix...]
Variations:
Some installers have a variant of this code in their .dist file, or even no .dist file at all. Examples I've found so far:
- Airport 4.2 has a function volumeCheckTiger() instead, with some other minor syntax changes, but the block to be commented out is still basically the same.
- iSync 2.1 has no .dist file, and has a completely separate "VolumeCheck" Perl script inside the /Content/Resources folder, with its own "VolumeCheck.strings" dictionary in the English.lproj folder. My Perl is rusty, so I'm still working on how to disable the condition inside "DO_CHECKS". My first attempt to comment out the check caused an index error, even though I was able to do just that in other cases (see below).
- iTunes 6 adds multiple nested packages, since it also includes the iPod and iTunes Phone drivers. Although it does have a .dist file, it uses the separate VolumeCheck Perl script instead of using the Javascript function. All 3 packages (iPodDriverJag, iTunesPhoneDriver, iTunesX) needed to have its own VolumeCheck script blocked out, plus iTunesX.dist had to have its "options rootVolumeOnly" set to "false".
- Java 1.3.1/1.4.2r2 actually had the IFPkgFlagRootVolumeOnly flag set in the Info.plist. However, this was a red herring, as setting the value to "false" had no effect. The real change was again in the .dist file, this time in the "options" section, by changing rootVolumeOnly to false.
- XCode Tools had IFPkgFlagRootVolumeOnly set to true in Info.plist, and a VolumeCheck script. This time I was able to comment out just the root volume check in the VolumeCheck DO_CHECKS function, but unlike with Java I also had to change the Info.plist entry to false.
Full Story
I've recently started building some new reference system installations for use in system restores, troubleshooting, etc. I wanted as clean of an updated Tiger install as possible, so I made a new partition on an external drive. I also cloned the Tiger Install DVD to a compressed disk image on another partition of the drive, and then ran the "Install Mac OS X" application off the mounted volume.
Of course, this only prompted the Tiger installer's default behavior of wanting to reboot off the DVD before running the installation. As I'm sure has been covered here before, I got around this by running OSInstall.pkg directly off the disk image from /System/Installation/Packages/. This let me target the new blank partition, do a Easy/Custom install, and build a new Tiger system in about 7 minutes.
I already had a 10.4.2 Combo Updater disk image, so I mounted that and ran it against the new Tiger partition ("SafetyOS") with no problems. I then needed to find out what other updates post-dated the 10.4.2 release, so using another scratch partition, I ran Carbon Copy Cloner to duplicate the new "SafetyOS" system to a "BaseOS" system. I set BaseOS as the Startup Disk, and booted into it to run Software Update. I downloaded all the installer packages for future use, then booted back into my core system to run them against SafetyOS.
Here's where I ran into my problem: while some of the updaters would run against SafetyOS without running under it, others complained that they could only be run on the boot volume and put the stop sign on all but my running system in the volume select screen. Which updaters I could use seemed to follow no clear pattern - some application updates were boot-only, while some system updates were not. So while I could run Safari 2.01 Update along with Security Update 2005-007 & 008, for example, AirPort 4.2, DVD Player 4.6/4.6.1, iSync 2.1, iTunes 6.01, Java 1.3.1/1.4.2r2, QuickTime 7.0.3, and XCode Tools all refused to update SafetyOS unless I was booted into it.
I figured I'd dig through the .plist files in the installer packages, comparing a boot-locked and a regular installer, and see if I could find what triggered the restriction. The "IFPkgFlagRootVolumeOnly" flag in Info.plist looked promising, but even on boot-locked installers, it was usually set to "false." All the other .plist files I reviewed in Contents and Resources proved fruitless, so I tried the .strings files in the English.lproj folder. In "Localizable.strings" I found a reference to the error message, "ERROR_BOOTVOL," that appears in the installer when you click on any non-boot volume. The non-locked installer didn't have this string listed.
I started checking the package files for any use of that string, and on a whim I tried opening the .dist file of the DVDPlayerUpdate.pkg in BBEdit. Doing a Find for the string quickly highlighted the if{} block under the volumeCheck() function which is apparently called whenever you click on a volume on the select screen. Commenting that out with standard HTML tags and reloading the installer proved to do the trick. Well, until I checked AirPort's installer, which was slightly different. And then iSync, which used a different script (and language, even). Then Java, which didn't use a script at all, but used an "options" dictionary entry. And so on, with all the variations listed above.
After going through all these installers, what's struck me is how inconsistent they are. Different scripts are used to do the same functions over separate installs, and some recreate functionality (like the root volume check) that are built into the Installer. Likewise, the version check algorithms seem to be custom-written each time, with many giving inaccurate results (e.g. trying to install QuickTime 7.0.3 on a volume with no system at all gives the alert "A newer version of this software is already installed"). I suppose Apple has different teams rolling up the installers, each using variations of the same process, but it must not be completely automated. It's also a little confusing whether the .plist files have an effect on the actual install (as they did with Xcode), or whether they require other code-behinds to trigger features like the root-system check (as Xcode also included one, or as seemed to occur with iSync).
It's good that the install packages are open to this kind of hacking, but I wonder if there is simply an easier way to build an up-to-date system without running it as the boot OS. This has been a longtime peeve on mine in keeping Windows system images up to date, with the horrendous number of separate installs you need to do and Microsoft's refusal to do point releases after a major OS roll-out.
