Creating customized OS X installer disk images for VMware Fusion
My preferred way to create VMs in VMware Fusion is by leveraging NetBoot and DeployStudio, but not all environments have access to NetBoot or DeployStudio. For those environments, there’s now a scripted way to create customized OS X 10.7.x or 10.8.x installer disk images for use with VMware Fusion. This allows the creation of OS X VMs in VMware Fusion that can configure themselves in an automated fashion without needing access to either NetBoot or server resources. See below the jump for the details.
The script below prepares a customized OS X installer disk image for use with VMware Fusion. It’s adapted from the prepare_iso script created by Tim Sutton.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Preparation script for a customized OS X installer for use with VWware Fusion | |
# | |
# What the script does, in more detail: | |
# | |
# 1. Mounts the InstallESD.dmg using a shadow file, so the original DMG is left | |
# unchanged. | |
# 2. minstallconfig.xml is also copied, which is looked for by the installer environment's | |
# rc.* files that first load with the system. This allows us to never actually modify the | |
# BaseSystem.dmg and only drop in these extra files. | |
# 3. Additional installer packages can be added using First Boot Package Install.pkg, | |
# which is added to the OS X install by way of the OSInstall.collection file. The instructions | |
# on how to use this package are documented here: | |
# https://derflounder.wordpress.com/2013/05/13/first-boot-package-install-pkg/ | |
# | |
# Original script written by Tim Sutton: | |
# https://github.com/timsutton/osx-vm-templates/tree/master/prepare_iso | |
# | |
# Thanks: (brought over from Tim's original script) | |
# Idea and much of the implementation thanks to Pepijn Bruienne, who's also provided | |
# some process notes here: https://gist.github.com/4542016. The sample minstallconfig.xml, | |
# use of OSInstall.collection and readme documentation provided with Greg Neagle's | |
# createOSXInstallPkg tool also proved very helpful. (http://code.google.com/p/munki/wiki/InstallingOSX) | |
# User creation via package install method also credited to Greg, and made easy with Per | |
# Olofsson's CreateUserPkg (http://magervalp.github.io/CreateUserPkg) | |
usage() { | |
cat <<EOF | |
Usage: | |
$(basename "$0") "/path/to/InstallESD.dmg" /path/to/output/directory | |
$(basename "$0") "/path/to/Install OS X [Mountain] Lion.app" /path/to/output/directory | |
Description: | |
Converts a 10.7/10.8 installer image to a new image that contains components | |
used to perform an automated installation. The new image will be named | |
'OSX_InstallESD_[osversion].dmg.' | |
EOF | |
} | |
msg_status() { | |
echo "\033[0;32m– $1\033[0m" | |
} | |
msg_error() { | |
echo "\033[0;31m– $1\033[0m" | |
} | |
if [ $# -eq 0 ]; then | |
usage | |
exit 1 | |
fi | |
if [ $(id -u) -ne 0 ]; then | |
msg_error "This script must be run as root, as it saves a disk image with ownerships enabled." | |
exit 1 | |
fi | |
ESD="$1" | |
if [ ! -e "$ESD" ]; then | |
msg_error "Input installer image $ESD could not be found! Exiting.." | |
exit 1 | |
fi | |
if [ -d "$ESD" ]; then | |
# we might be an install .app | |
if [ -e "$ESD/Contents/SharedSupport/InstallESD.dmg" ]; then | |
ESD="$ESD/Contents/SharedSupport/InstallESD.dmg" | |
else | |
msg_error "Can't locate an InstallESD.dmg in this source location $ESD!" | |
fi | |
fi | |
SCRIPT_DIR="$(cd $(dirname "$0"); pwd)" | |
DEFINITION_DIR="$(cd $SCRIPT_DIR/..; pwd)" | |
if [ "$2" == "" ]; then | |
msg_error "Currently an explicit output directory is required as the second argument." | |
exit 1 | |
else | |
OUT_DIR="$2" | |
fi | |
if [ ! -d "$OUT_DIR" ]; then | |
msg_status "Destination dir $OUT_DIR doesn't exist, creating.." | |
mkdir -p "$OUT_DIR" | |
fi | |
if [ -e "$ESD.shadow" ]; then | |
msg_status "Removing old shadow file.." | |
rm "$ESD.shadow" | |
fi | |
MNT_ESD=$(/usr/bin/mktemp -d /tmp/vmware-osx-esd.XXXX) | |
SHADOW_FILE=$(/usr/bin/mktemp /tmp/vmware-osx-shadow.XXXX) | |
rm "$SHADOW_FILE" | |
msg_status "Attaching input OS X installer image with shadow file.." | |
hdiutil attach "$ESD" -mountpoint "$MNT_ESD" -shadow "$SHADOW_FILE" -nobrowse -owners on | |
if [ $? -ne 0 ]; then | |
[ ! -e "$ESD" ] && msg_error "Could not find $ESD in $(pwd)" | |
msg_error "Could not mount $ESD on $MNT_ESD" | |
exit 1 | |
fi | |
DMG_OS_VERS=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$MNT_ESD/System/Library/CoreServices/SystemVersion.plist") | |
DMG_OS_VERS_MAJOR=$(echo $DMG_OS_VERS | awk -F "." '{print $2}') | |
DMG_OS_BUILD=$(/usr/libexec/PlistBuddy -c 'Print :ProductBuildVersion' "$MNT_ESD/System/Library/CoreServices/SystemVersion.plist") | |
OUTPUT_DMG="$OUT_DIR/OSX_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.dmg" | |
if [ -e "$OUTPUT_DMG" ]; then | |
msg_error "Output file $OUTPUT_DMG already exists! We're not going to overwrite it, exiting.." | |
hdiutil detach "$MNT_ESD" | |
exit 1 | |
fi | |
SUPPORT_DIR="$SCRIPT_DIR/support" | |
# Add First Boot Package Install.pkg to the OS X installer | |
FIRSTBOOT_PKG="$SUPPORT_DIR/First Boot Package Install.pkg" | |
# Add our auto-setup files: minstallconfig.xml and OSInstall.collection | |
msg_status "Adding automated components.." | |
mkdir "$MNT_ESD/Packages/Extras" | |
cp "$SUPPORT_DIR/minstallconfig.xml" "$MNT_ESD/Packages/Extras/" | |
cp "$SUPPORT_DIR/OSInstall.collection" "$MNT_ESD/Packages/" | |
cp -r "$FIRSTBOOT_PKG" "$MNT_ESD/Packages/" | |
rm -rf "$SUPPORT_DIR/tmp" | |
msg_status "Unmounting.." | |
hdiutil detach "$MNT_ESD" | |
msg_status "Converting to final output file.." | |
hdiutil convert -format UDZO -o "$OUTPUT_DMG" -shadow "$SHADOW_FILE" "$ESD" | |
rm "$SHADOW_FILE" | |
rm -rf "$MNT_ESD" | |
if [ -n "$SUDO_UID" ] && [ -n "$SUDO_GID" ]; then | |
msg_status "Fixing permissions.." | |
chown -R $SUDO_UID:$SUDO_GID "$OUT_DIR" | |
fi | |
msg_status "Checksumming output image.." | |
MD5=$(md5 -q "$OUTPUT_DMG") | |
msg_status "MD5: $MD5" | |
msg_status "Done. Built image is located at $OUTPUT_DMG." |
Downloading the script and support files
Download a .zip archive containing all needed files from my GitHub repo.This will give you both the create_vmware_osx_install_dmg script and a directory named support which contains files that the script will be copying into the completed disk image.
Both the create_vmware_osx_install_dmg script and the support directory must be stored in the same directory in order for the script to work properly.
Once you have the .zip archive download and uncompressed, go into the support directory and unzip the First_Boot_Package_Install.zip file. First Boot Package Install.pkg is used by the script so it’ll need to be unzipped and prepared before running the script.
Configuring First Boot Package Install.pkg for use with the script
First Boot Package Install.pkg is an installer package that enables other packages to be installed at first boot. The script adds First Boot Package Install.pkg to the OS X installer and allows installer packages that can’t run in the OS X Installer environment to be be installed during the first boot of the VM.
NOTE: The customized OS X installer will have an upper limit of 350 MBs of available space for added packages. This is sufficient space for basic configuration, payload-free or bootstrapping packages, but it’s not a good idea to add Microsoft Office or similar large installers to this installer.
For details on how to configure First Boot Package Install.pkg, please see this post:
https://derflounder.wordpress.com/2013/05/13/first-boot-package-install-pkg/
Running the script to create a customized OS X install .dmg file
Once you have First Boot Package Install.pkg configured with your packages, run the create_vmware_osx_install_dmg script with two arguments:
A. The path to an Install OS X [Mountain] Lion.app or the InstallESD.dmg contained within.
B. An directory to store the completed disk image in.
Example usage:
If you have a 10.8.4 Mountain Lion installer available, run this command:
sudo /path/to/create_vmware_osx_install_dmg.sh "/Applications/Install OS X Mountain Lion.app" /path/to/output_directory
This should produce a DMG file inside output_directory that’s named OSX_InstallESD_10.8.4_12E55.dmg. This DMG will install both OS X 10.8.4 and First Boot Package Install.pkg.
Creating a VM with the customized OS X install .dmg file
1. Launch VMWare Fusion 5.x
2. In VMWare Fusion, select New… under the File menu to set up a new VM
3. In the Create New Virtual Machine window, select Continue without disc.
4. In the Installation Media window, select Use operating system installation disc or image, then click on Choose a disc or disc image…
5. Select your customized OS X install disk image file
6. In the Choose Operating System window, set OS as appropriate. In this example, I’m setting it as follows:
Operating System: Apple Mac OS X
Version: Mac OS X 10.8 64-bit
7. In the Finish window, select Customize Settings if desired. Otherwise, click Finish.
8. Save the VM file in a convenient location.
The VM is now configured and set to use the customized OS X installer disk image. To install OS X and the packages included with First Boot Package Install.pkg, start the VM and then do nothing. The VM should begin automatically installing OS X on the VM’s boot drive, followed by the installation of First Boot Package Install.pkg.
Once the installation completes, the VM will then reboot.
On reboot, the login window will be stopped from loading while the packages included with First Boot Package Install.pkg are installed. Once the packages finish installing, the VM will reboot again.
After the second reboot, the VM should now be automatically configured with the desired applications and settings.
Recent Comments