Wednesday, May 25, 2005

OS X esoterica: roots in NeXTStep and the Installer

The following as a comment in a discussion thread on the location of OS X applications. In general OS X applications, once installed, should not be relocated. This is similar to Windows, but in addition many OS X applications have very rigid requirements for installation paths. This is more restrictive than Windows.

It's also very strange for MacOS veterans. The original MacOS maintained a superb level of indirection between an applications physical storage and its unique indentifier. This level of indirection was broken with OS X, a result of the UNIX roots of NeXTStep and thus of OS X.

Alex Blewitt describes this in some detail. For OS X geeks his discussion is quite revealing. Emphases mine. Note the nasty bug -- in general I avoid symlinks.
# Alex Blewitt wrote on May 25th, 2005 at 1:09 am:

The applications can’t easily be moved and then referenced with a symbolic link. It might stand a better chance with an HFS Alias, but that’s no good if it’s on a different partition, since HFS Aliases only work on the same HFS partition (IIRC).

The problem is that the Mac OS X Installer program (which dates back to NeXT days, by the way, not Mac OS proper) packages its applications up in a compressed format called PAX; which is rather like the Unix TAR but just different. Unfortunately, the un-PAXer engine (pax -r) will overwrite symlink’d directories and replace them with real directories instead. This has been a known bug since time began; it may have been fixed in 10.4 but I’m not expecting it to have been.

Although most apps can be moved, there are a few ‘gotchas’. Unlike comment 3 indicates, most apps don’t write into /bin or /usr/bin (the only ones really being stuff like X.app and XCode.app which include command-line-compilery things). However, they can install private frameworks into /System/Library/PrivateFrameworks/ (which is a kind of Mac OS X dynamic link library, if you’re interested). The iLife apps are an example of this, as are the Apple Pro tools (which use Pro Application Support, or some arrangement of those words). [jf: these framworks have resources which remind me of old MacOS apps]

Since the app in a few cases is a shell to the underlying framework (e.g. Safari is a set of widgets around the WebCore framework, QuicktimePlayer is a set of widgets around the Quicktime framework etc.) it’s not safe to just move the app elsewhere, as it will rely on the framework versions too. This is one reason why they are all bodged to install only on / [jf: / is root] in case you’re interested; they have to write the app, and the framework in the OS partition there as well [jf: the path to the framework is a relative path]. For example, you can’t (easily) set up iPhoto.app on a networked share, because you also need the framework set up as well. (However, you can set the framework up on a networked share too …)

It’s also worth noting that ‘Applications’ is the well-known name for putting apps in, which is why if you create a user account and put a directory called ‘Applications’ in, it turns into the specific icon for an Applications directory. Ditto for Library, and Mac OS X will go through a search path for finding apps:
~/Applications /Applications /Network/Applications (/Developer/Applications)
as well as libraries:
~/Library /Library /System/Library /Network/Library (/Developer/Library ?)

From this, it’s relatively easy to create a share and mount a directory into the /Network/Applications and /Network/Library which are part of the known search path. Whilst it doesn’t matter too much about the applications, it’s really handy having the frameworks available in /Network/Library as well. To achieve this, you’ll need a server capable of hosting shares (I use NFS; I’ve found AFP to be problematic at best of times, but it’s getting better) and then mount them into /Network/Applications and /Network/Library.

For example, if you have a FireWire drive that you want to put stuff in, stick them in /Volumes/MyBigDrive/Applications (and ../Libraries as well). Then, set up an NFS export (see Mac OS X hints for how :-) for /Volumes/MyBigDrive/Applications and then re-mount it as /Network/Applications; ditto for Libraries. You should then see them in the /Network tab in your drawer.

When updates come out, you can install them onto a different ‘target’, although (to my knowledge) not via the Installer app itself. Download the package (Download and Keep from Software Update), then run it with ‘installer -target /Volumes/MyBigDrive -pkg SecUpd_1023.pkg’. (If you want to get rid of excess languages, you can also add -lang en to only install English)

A few of the apps (mostly the iLife ones) will attempt to complain if the drive isn’t / — but that can be fixed. There’s a file called something like preinstall in the SecUpd_1023.pkg/Contents/Resources directory; there’s usually something like ‘if [ $drive = ‘/’ ]; echo “You must install this on /”; exit 1′ in there. Removing this line, or getting rid of the exit will allow you to install it anywhere you want.

The other approach (and the one that Apple wants people to do) is to image a virgin Mac with the disk image utility, and then make the image available via NetBoot. That way, all macs have exactly the same image at all times; when an update comes in, you can test it on your ‘virgin’ mac, and then push the image everywhere. I’m not sure if these imaging tools are only part of Mac OS X Server, but given that they are just DiskUtility type ‘make an image of this hard drive’ it’s not entirely impossible to do it outside of a Server environment.

Of course, I’ve not had time to go into the /Library/Receipts folder for what you’ve installed where, but you might want to move the receipts into the shared /Network/Library/Receipts for the packages that you have installed on the shared drive in the past…

No comments: