main fd2f2d972e8c cached
5 files
17.3 KB
4.9k tokens
1 requests
Download .txt
Repository: rtrouton/create_os_x_vm_install_dmg
Branch: main
Commit: fd2f2d972e8c
Files: 5
Total size: 17.3 KB

Directory structure:
gitextract_syrpmg9f/

├── LICENSE
├── README.txt
├── create_vmware_osx_install_dmg.sh
└── support/
    ├── OSInstall.collection
    └── minstallconfig.xml

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2014 rtrouton

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.txt
================================================
Please Read:
------------

macOS 10.12.4 introduced a change that prevents the addition of third-party packages to the OS installer. This script uses the addition of a third-party installer package, so unfortunately this script cannot be used to generate 10.12.4 or later OS installers.

If you need to build a macOS 10.12.x VM, my recommendation at this point is to use the macOS 10.12.3 installer. Once the OS is installed, update to later versions of macOS Sierra as a post-installation task.



This script prepares customized OS X installer disk images for use with VMware Fusion and ESXi. It's adapted from the prepare_iso script created by Tim Sutton: https://github.com/timsutton/osx-vm-templates/tree/master/prepare_iso

Pre-requisites: 

1. This script and the associated support directory. This script and the support directory must be both stored in the same directory in order for the script to work properly.

2. A 10.7.x, 10.8.x, 10.9.x, 10.10.x, 10.11.x, or 10.12.x installer from Apple's Mac App Store.


Running the script: 

Run the create_vmware_osx_install_dmg.sh script with two arguments: the path to an "Install OS X.app" or the InstallESD.dmg contained within, and an output directory. 


Example usage: 

If you have a 10.11.x El Capitan installer available, run this command:

sudo /path/to/create_vmware_osx_install_dmg.sh "/Applications/Install OS X El Capitan.app" /path/to/output_directory

This should produce a DMG file at output_directory that's named OSX_InstallESD_10.11_15A284.dmg. An MD5 checksum is printed at the end of the process.


What the script does:

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 a first boot package, which is added to 
   the OS X install by way of the OSInstall.collection file. The script is expecting the following:

   A. That the first boot package is named "First Boot Package Install.pkg" (no quotes)
   B. That the first boot package is stored in the support directory.
   
   This first boot package can be generated by First Boot Package Install Generator.app, which will generate a 
   distribution-style flat package that can be used with 10.7 / 10.8 / 10.9 / 10.10 / 10.11 OS installs.

   The instructions for using this tool to generate first boot packages are documented here: 
   https://github.com/rtrouton/First_Boot_Package_Install_Generator

4. If desired, a second disk image in .iso format can be generated for use with VMware ESXi
   servers running on Apple hardware. 


Once you have the customized DMG file created, you can choose it as an install disk image in VMware Fusion when creating virtual machines in VMware Fusion.

This script has been tested with Apple's 10.7.5, 10.8.5, 10.9.5, 10.10.5, 10.11.6, and 10.12.0 installers from the Mac App Store.




NOTES: 

1. A pre-generated First Boot Package Install.pkg is stored in the support directory as a zip file named First_Boot_Package_Install.zip. Unzip the file before running the script. This first boot package will automatically install all available Apple software updates following the OS installation, but provide no other customization.

2. The 10.9.x disk images created with this method will not install a recovery partition into a VM. As a workaround, it appears that this can be addressed via using Per Olofsson’s Create Recovery Partition Installer to generate an installer that can install the missing recovery partition:

Create Recovery Partition Installer is available from here on GitHub:
https://github.com/MagerValp/Create-Recovery-Partition-Installer

Unfortunately, that installer would be too large to include as part of First Boot Package Install’s payload (available space is around 350 MBs, the Recovery Partition installer is around 485 MBs.)

In my testing, 10.7.x, 10.8.x, 10.10.x, 10.11.x and 10.12.x disk images will successfully install a recovery partition into the VM.


================================================
FILE: create_vmware_osx_install_dmg.sh
================================================
#!/bin/sh
#
# Preparation script for a customized OS X installer for use with VWware Fusion and ESXi
# 
# 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 a first boot package which *must* be named
#    First Boot Package Install.pkg, which is added to the OS X install by way of the OSInstall.collection file.
#    
#    This first boot package can be generated by First Boot Package Install Generator.app, which will 
#    generate a distribution-style flat package that can be used with OS installs. The instructions
#    for using this tool to generate first boot packages are documented here: 
#    https://github.com/rtrouton/First_Boot_Package_Install_Generator
#
# 4. If desired, a second disk image in .iso format can be generated for use with VMware ESXi
#    servers running on Apple hardware. 
#
# 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)
#
# Antony Blakey for updates to support OS X 10.11:
# https://github.com/timsutton/osx-vm-templates/issues/40

usage() {
	cat <<EOF
Usage:
$(basename "$0") "/path/to/InstallESD.dmg" /path/to/output/directory
$(basename "$0") "/path/to/Install OS X [Name].app" /path/to/output/directory

Description:
Converts an OS X 10.7 and later, or macOS 10.12 and later, 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.' or macOS_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

# Script will prompt user if they want an additional image in .iso
# format for use with a VMware ESXi server.

echo "Do you also want an ISO disk image for use with VMware ESXi?"
select yn in "Yes" "No"; do
	case $yn in
		Yes) ISO=1; break;;
		No) msg_error "ISO disk image will not be created. Proceeding.."; break;;
	esac
done

MNT_ESD=$(/usr/bin/mktemp -d /tmp/vmware-apple-esd.XXXX)
SHADOW_FILE=$(/usr/bin/mktemp /tmp/vmware-apple-shadow.XXXX)
rm "$SHADOW_FILE"
msg_status "Attaching input 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

msg_status "Mounting BaseSystem.."
 BASE_SYSTEM_DMG="$MNT_ESD/BaseSystem.dmg"
 MNT_BASE_SYSTEM=$(/usr/bin/mktemp -d /tmp/vmware-apple-basesystem.XXXX)
 [ ! -e "$BASE_SYSTEM_DMG" ] && msg_error "Could not find BaseSystem.dmg in $MNT_ESD"
 hdiutil attach "$BASE_SYSTEM_DMG" -mountpoint "$MNT_BASE_SYSTEM" -nobrowse -owners on
 if [ $? -ne 0 ]; then
 	msg_error "Could not mount $BASE_SYSTEM_DMG on $MNT_BASE_SYSTEM"
 	exit 1
fi

SYSVER_PLIST_PATH="$MNT_BASE_SYSTEM/System/Library/CoreServices/SystemVersion.plist"


DMG_OS_VERS=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$SYSVER_PLIST_PATH")
DMG_OS_VERS_MAJOR=$(echo $DMG_OS_VERS | awk -F "." '{print $2}')
DMG_OS_VERS_MINOR=$(echo $DMG_OS_VERS | awk -F "." '{print $3}')
DMG_OS_BUILD=$(/usr/libexec/PlistBuddy -c 'Print :ProductBuildVersion' "$SYSVER_PLIST_PATH")

if [[ $DMG_OS_VERS_MAJOR -ge 12 ]]; then
  OSNAME=macOS
else
  OSNAME=OSX
fi

msg_status "$OSNAME version detected: 10.$DMG_OS_VERS_MAJOR.$DMG_OS_VERS_MINOR, build $DMG_OS_BUILD"

OUTPUT_DMG="$OUT_DIR/${OSNAME}_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"
    hdiutil detach -force "$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"

if [[ -e "$FIRSTBOOT_PKG" ]]; then
   msg_status "$FIRSTBOOT_PKG detected. Proceeding..."
else
	msg_error "$FIRSTBOOT_PKG not found! This is needed for the OS to install properly, exiting.."
	msg_error "The script is expecting the following:"
	msg_error "A. That a first boot installer package is stored in $SUPPORT_DIR."
	msg_error "B. That the first boot installer package is named as follows: First Boot Package Install.pkg"
	msg_status ""	
	msg_status "A pre-generated First Boot Package Install.pkg should be stored in $SUPPORT_DIR as a zip file named First_Boot_Package_Install.zip."
	msg_status "This first boot package will automatically install all available Apple software updates following the OS installation, but provide no other customization."
	msg_status "If you don't want additional customization of the OS installer, just unzip the First_Boot_Package_Install.zip file before running the script."
	msg_status ""
	msg_status "If you want customization, the first boot package can be generated by First Boot Package Install Generator.app,"
	msg_status "which will generate a distribution-style flat package that can be used with $OSNAME installs."
	msg_status ""
	msg_status "The instructions for using this tool to generate first boot packages are documented here:"
	msg_status "https://github.com/rtrouton/First_Boot_Package_Install_Generator"
	exit 1
fi

# We'd previously mounted this to check versions
hdiutil detach "$MNT_BASE_SYSTEM"

BASE_SYSTEM_DMG_RW="$(/usr/bin/mktemp /tmp/vmware-apple-basesystem-rw.XXXX).dmg"

msg_status "Creating empty read-write DMG located at $BASE_SYSTEM_DMG_RW.."
hdiutil create -o "$BASE_SYSTEM_DMG_RW" -size 10g -layout SPUD -fs HFS+J
hdiutil attach "$BASE_SYSTEM_DMG_RW" -mountpoint "$MNT_BASE_SYSTEM" -nobrowse -owners on

msg_status "Restoring the BaseSystem to the read-write DMG using asr.."

# This asr restore is needed as of 10.11 DP7 and up. See
# https://github.com/timsutton/osx-vm-templates/issues/40
#
# Note that when the restore completes, the volume is automatically re-mounted
# into /Volumes instead of the previous mountpoint. It is also visible as the 
# "-nobrowse" option is not applied.

asr restore --source "$BASE_SYSTEM_DMG" --target "$MNT_BASE_SYSTEM" --noprompt --noverify --erase

# To fix the volume being visible when remounted, check for the new
# volume which is mounted in /Volumes and unmount it.

if [[ -e "/Volumes/OS X Base System" ]]; then
   umount "/Volumes/OS X Base System"
elif [[ -e "/Volumes/Mac OS X Base System" ]]; then
   umount "/Volumes/Mac OS X Base System"
fi

# Remounting the disk image outside of /Volumes with the '-nobrowse' option.

hdiutil attach "$BASE_SYSTEM_DMG_RW" -mountpoint "$MNT_BASE_SYSTEM" -nobrowse -owners on

if [[ $DMG_OS_VERS_MAJOR -ge 9 ]]; then
    BASESYSTEM_OUTPUT_IMAGE="$OUTPUT_DMG"
    PACKAGES_DIR="$MNT_BASE_SYSTEM/System/Installation/Packages"

    rm "$PACKAGES_DIR"
	msg_status "Moving 'Packages' directory from the ESD to BaseSystem.."
	mv -v "$MNT_ESD/Packages" "$MNT_BASE_SYSTEM/System/Installation/"

	# This isn't strictly required for Mavericks, but Yosemite will consider the
	# installer corrupt if this isn't included, because it cannot verify BaseSystem's
	# consistency and perform a recovery partition verification
	msg_status "Copying in original BaseSystem dmg and chunklist.."
	cp "$MNT_ESD/BaseSystem.dmg" "$MNT_BASE_SYSTEM/"
	cp "$MNT_ESD/BaseSystem.chunklist" "$MNT_BASE_SYSTEM/"
else
    BASESYSTEM_OUTPUT_IMAGE="$MNT_ESD/BaseSystem.dmg"
    rm "$BASESYSTEM_OUTPUT_IMAGE"
	PACKAGES_DIR="$MNT_ESD/Packages"
fi

# Adding a custom rc.cdrom.local that will automatically erase the VM's
# boot drive. Also adding our auto-setup files: minstallconfig.xml and 
# OSInstall.collection

msg_status "Adding automated components.."
CDROM_LOCAL="$MNT_BASE_SYSTEM/private/etc/rc.cdrom.local"
echo "diskutil eraseDisk jhfs+ \"Macintosh HD\" GPTFormat disk0" > "$CDROM_LOCAL"
chmod a+x "$CDROM_LOCAL"
mkdir "$PACKAGES_DIR/Extras"
cp "$SUPPORT_DIR/minstallconfig.xml" "$PACKAGES_DIR/Extras/"
cp "$SUPPORT_DIR/OSInstall.collection" "$PACKAGES_DIR/"
cp -r "$FIRSTBOOT_PKG" "$PACKAGES_DIR/"
rm -rf "$SUPPORT_DIR/tmp"

msg_status "Unmounting BaseSystem.."
hdiutil detach "$MNT_BASE_SYSTEM"

if [ $DMG_OS_VERS_MAJOR -lt 9 ]; then
	msg_status "Pre-Mavericks we save back the modified BaseSystem to the root of the ESD."
	hdiutil convert -format UDZO -o "$MNT_ESD/BaseSystem.dmg" "$BASE_SYSTEM_DMG_RW"
fi

msg_status "Unmounting.."
hdiutil detach "$MNT_ESD"

msg_status "Converting to .dmg disk image.."

if [[ $DMG_OS_VERS_MAJOR -ge 9 ]]; then
	msg_status "On Mavericks and later, the entire modified BaseSystem is our output dmg."
	hdiutil convert -format UDZO -o "$OUTPUT_DMG" "$BASE_SYSTEM_DMG_RW"
else
	msg_status "Pre-Mavericks we're modifying the original ESD file."
	hdiutil convert -format UDZO -o "$OUTPUT_DMG" -shadow "$SHADOW_FILE" "$ESD"
fi

rm -rf "$MNT_ESD" "$SHADOW_FILE" "$BASE_SYSTEM_DMG_RW"

if [[ $ISO = 1 ]]; then
   OUTPUT_ISO="$OUT_DIR/${OSNAME}_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.iso"
   msg_status "Converting to .iso disk image...."
   /usr/bin/hdiutil convert "$OUTPUT_DMG" -format UDTO -o "$OUTPUT_ISO"
   /bin/mv $OUT_DIR/${OSNAME}_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.iso.cdr "$OUTPUT_ISO"
fi

if [[ -n "$SUDO_UID" ]] && [[ -n "$SUDO_GID" ]]; then
	msg_status "Fixing permissions.."
	chown -R $SUDO_UID:$SUDO_GID "$OUT_DIR"
fi

msg_status "Checksumming .dmg disk image.."
MD5=$(md5 -q "$OUTPUT_DMG")
msg_status "MD5: $MD5"
msg_status "Built .dmg disk image is located at $OUTPUT_DMG."

if [[ -f "$OUTPUT_ISO" ]]; then
  msg_status "Checksumming .iso disk image.."
  MD5=$(md5 -q "$OUTPUT_ISO")
  msg_status "MD5: $MD5"
  msg_status "Built .iso disk image is located at $OUTPUT_ISO."
fi

msg_status "Build process finished."

================================================
FILE: support/OSInstall.collection
================================================
<?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">
<array>
	<string>/System/Installation/Packages/OSInstall.mpkg</string>
	<string>/System/Installation/Packages/OSInstall.mpkg</string>
	<string>/System/Installation/Packages/First Boot Package Install.pkg</string>
</array>
</plist>



================================================
FILE: support/minstallconfig.xml
================================================
<?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>InstallType</key>
	<string>automated</string>
	<key>Language</key>
	<string>en</string>
	<key>Package</key>
	<string>/System/Installation/Packages/OSInstall.collection</string>
	<key>Target</key>
	<string>/Volumes/Macintosh HD</string>
	<key>TargetName</key>
	<string>Macintosh HD</string>
</dict>
</plist>
Download .txt
gitextract_syrpmg9f/

├── LICENSE
├── README.txt
├── create_vmware_osx_install_dmg.sh
└── support/
    ├── OSInstall.collection
    └── minstallconfig.xml
Condensed preview — 5 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
  {
    "path": "LICENSE",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 rtrouton\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "README.txt",
    "chars": 4187,
    "preview": "Please Read:\n------------\n\nmacOS 10.12.4 introduced a change that prevents the addition of third-party packages to the O"
  },
  {
    "path": "create_vmware_osx_install_dmg.sh",
    "chars": 11551,
    "preview": "#!/bin/sh\n#\n# Preparation script for a customized OS X installer for use with VWware Fusion and ESXi\n# \n# What the scrip"
  },
  {
    "path": "support/OSInstall.collection",
    "chars": 396,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "support/minstallconfig.xml",
    "chars": 484,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  }
]

About this extraction

This page contains the full source code of the rtrouton/create_os_x_vm_install_dmg GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 5 files (17.3 KB), approximately 4.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!