[
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 rtrouton\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.txt",
    "content": "Please Read:\n------------\n\nmacOS 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.\n\nIf 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.\n\n\n\nThis 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\n\nPre-requisites: \n\n1. 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.\n\n2. 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.\n\n\nRunning the script: \n\nRun 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. \n\n\nExample usage: \n\nIf you have a 10.11.x El Capitan installer available, run this command:\n\nsudo /path/to/create_vmware_osx_install_dmg.sh \"/Applications/Install OS X El Capitan.app\" /path/to/output_directory\n\nThis 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.\n\n\nWhat the script does:\n\n1. Mounts the InstallESD.dmg using a shadow file, so the original DMG is left unchanged.\n\n2. minstallconfig.xml is also copied, which is looked for by the installer environment's \n   rc.* files that first load with the system. This allows us to never actually modify the \n   BaseSystem.dmg and only drop in these extra files.\n\n3. Additional installer packages can be added using a first boot package, which is added to \n   the OS X install by way of the OSInstall.collection file. The script is expecting the following:\n\n   A. That the first boot package is named \"First Boot Package Install.pkg\" (no quotes)\n   B. That the first boot package is stored in the support directory.\n   \n   This first boot package can be generated by First Boot Package Install Generator.app, which will generate a \n   distribution-style flat package that can be used with 10.7 / 10.8 / 10.9 / 10.10 / 10.11 OS installs.\n\n   The instructions for using this tool to generate first boot packages are documented here: \n   https://github.com/rtrouton/First_Boot_Package_Install_Generator\n\n4. If desired, a second disk image in .iso format can be generated for use with VMware ESXi\n   servers running on Apple hardware. \n\n\nOnce 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.\n\nThis 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.\n\n\n\n\nNOTES: \n\n1. 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.\n\n2. 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:\n\nCreate Recovery Partition Installer is available from here on GitHub:\nhttps://github.com/MagerValp/Create-Recovery-Partition-Installer\n\nUnfortunately, 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.)\n\nIn 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.\n"
  },
  {
    "path": "create_vmware_osx_install_dmg.sh",
    "content": "#!/bin/sh\n#\n# Preparation script for a customized OS X installer for use with VWware Fusion and ESXi\n# \n# What the script does, in more detail:\n# \n# 1. Mounts the InstallESD.dmg using a shadow file, so the original DMG is left\n#    unchanged.\n#\n# 2. minstallconfig.xml is also copied, which is looked for by the installer environment's \n#    rc.* files that first load with the system. This allows us to never actually modify the \n#    BaseSystem.dmg and only drop in these extra files.\n#\n# 3. Additional installer packages can be added using a first boot package which *must* be named\n#    First Boot Package Install.pkg, which is added to the OS X install by way of the OSInstall.collection file.\n#    \n#    This first boot package can be generated by First Boot Package Install Generator.app, which will \n#    generate a distribution-style flat package that can be used with OS installs. The instructions\n#    for using this tool to generate first boot packages are documented here: \n#    https://github.com/rtrouton/First_Boot_Package_Install_Generator\n#\n# 4. If desired, a second disk image in .iso format can be generated for use with VMware ESXi\n#    servers running on Apple hardware. \n#\n# Original script written by Tim Sutton:\n# https://github.com/timsutton/osx-vm-templates/tree/master/prepare_iso\n#\n# Thanks: (brought over from Tim's original script)\n# Idea and much of the implementation thanks to Pepijn Bruienne, who's also provided\n# some process notes here: https://gist.github.com/4542016. The sample minstallconfig.xml,\n# use of OSInstall.collection and readme documentation provided with Greg Neagle's\n# createOSXInstallPkg tool also proved very helpful. (http://code.google.com/p/munki/wiki/InstallingOSX)\n#\n# User creation via package install method also credited to Greg, and made easy with Per\n# Olofsson's CreateUserPkg (http://magervalp.github.io/CreateUserPkg)\n#\n# Antony Blakey for updates to support OS X 10.11:\n# https://github.com/timsutton/osx-vm-templates/issues/40\n\nusage() {\n\tcat <<EOF\nUsage:\n$(basename \"$0\") \"/path/to/InstallESD.dmg\" /path/to/output/directory\n$(basename \"$0\") \"/path/to/Install OS X [Name].app\" /path/to/output/directory\n\nDescription:\nConverts an OS X 10.7 and later, or macOS 10.12 and later, installer image to a new image that contains components\nused to perform an automated installation. The new image will be named\n'OSX_InstallESD_[osversion].dmg.' or macOS_InstallESD_[osversion].dmg.\n\nEOF\n}\n\nmsg_status() {\n\techo \"\\033[0;32m-- $1\\033[0m\"\n}\nmsg_error() {\n\techo \"\\033[0;31m-- $1\\033[0m\"\n}\n\nif [ $# -eq 0 ]; then\n\tusage\n\texit 1\nfi\n\nif [ $(id -u) -ne 0 ]; then\n\tmsg_error \"This script must be run as root, as it saves a disk image with ownerships enabled.\"\n\texit 1\nfi\t\n\nESD=\"$1\"\nif [ ! -e \"$ESD\" ]; then\n\tmsg_error \"Input installer image $ESD could not be found! Exiting..\"\n\texit 1\nfi\n\nif [ -d \"$ESD\" ]; then\n\t# we might be an install .app\n\tif [ -e \"$ESD/Contents/SharedSupport/InstallESD.dmg\" ]; then\n\t\tESD=\"$ESD/Contents/SharedSupport/InstallESD.dmg\"\n\telse\n\t\tmsg_error \"Can't locate an InstallESD.dmg in this source location $ESD!\"\n\tfi\nfi\n\nSCRIPT_DIR=\"$(cd $(dirname \"$0\"); pwd)\"\nDEFINITION_DIR=\"$(cd $SCRIPT_DIR/..; pwd)\"\n\nif [ \"$2\" == \"\" ]; then\n    msg_error \"Currently an explicit output directory is required as the second argument.\"\n\texit 1\nelse\n\tOUT_DIR=\"$2\"\nfi\n\nif [ ! -d \"$OUT_DIR\" ]; then\n\tmsg_status \"Destination dir $OUT_DIR doesn't exist, creating..\"\n\tmkdir -p \"$OUT_DIR\"\nfi\n\nif [ -e \"$ESD.shadow\" ]; then\n\tmsg_status \"Removing old shadow file..\"\n\trm \"$ESD.shadow\"\nfi\n\n# Script will prompt user if they want an additional image in .iso\n# format for use with a VMware ESXi server.\n\necho \"Do you also want an ISO disk image for use with VMware ESXi?\"\nselect yn in \"Yes\" \"No\"; do\n\tcase $yn in\n\t\tYes) ISO=1; break;;\n\t\tNo) msg_error \"ISO disk image will not be created. Proceeding..\"; break;;\n\tesac\ndone\n\nMNT_ESD=$(/usr/bin/mktemp -d /tmp/vmware-apple-esd.XXXX)\nSHADOW_FILE=$(/usr/bin/mktemp /tmp/vmware-apple-shadow.XXXX)\nrm \"$SHADOW_FILE\"\nmsg_status \"Attaching input installer image with shadow file..\"\nhdiutil attach \"$ESD\" -mountpoint \"$MNT_ESD\" -shadow \"$SHADOW_FILE\" -nobrowse -owners on \nif [ $? -ne 0 ]; then\n\t[ ! -e \"$ESD\" ] && msg_error \"Could not find $ESD in $(pwd)\"\n\tmsg_error \"Could not mount $ESD on $MNT_ESD\"\n\texit 1\nfi\n\nmsg_status \"Mounting BaseSystem..\"\n BASE_SYSTEM_DMG=\"$MNT_ESD/BaseSystem.dmg\"\n MNT_BASE_SYSTEM=$(/usr/bin/mktemp -d /tmp/vmware-apple-basesystem.XXXX)\n [ ! -e \"$BASE_SYSTEM_DMG\" ] && msg_error \"Could not find BaseSystem.dmg in $MNT_ESD\"\n hdiutil attach \"$BASE_SYSTEM_DMG\" -mountpoint \"$MNT_BASE_SYSTEM\" -nobrowse -owners on\n if [ $? -ne 0 ]; then\n \tmsg_error \"Could not mount $BASE_SYSTEM_DMG on $MNT_BASE_SYSTEM\"\n \texit 1\nfi\n\nSYSVER_PLIST_PATH=\"$MNT_BASE_SYSTEM/System/Library/CoreServices/SystemVersion.plist\"\n\n\nDMG_OS_VERS=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' \"$SYSVER_PLIST_PATH\")\nDMG_OS_VERS_MAJOR=$(echo $DMG_OS_VERS | awk -F \".\" '{print $2}')\nDMG_OS_VERS_MINOR=$(echo $DMG_OS_VERS | awk -F \".\" '{print $3}')\nDMG_OS_BUILD=$(/usr/libexec/PlistBuddy -c 'Print :ProductBuildVersion' \"$SYSVER_PLIST_PATH\")\n\nif [[ $DMG_OS_VERS_MAJOR -ge 12 ]]; then\n  OSNAME=macOS\nelse\n  OSNAME=OSX\nfi\n\nmsg_status \"$OSNAME version detected: 10.$DMG_OS_VERS_MAJOR.$DMG_OS_VERS_MINOR, build $DMG_OS_BUILD\"\n\nOUTPUT_DMG=\"$OUT_DIR/${OSNAME}_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.dmg\"\nif [ -e \"$OUTPUT_DMG\" ]; then\n\tmsg_error \"Output file $OUTPUT_DMG already exists! We're not going to overwrite it, exiting..\"\n# \thdiutil detach \"$MNT_ESD\"\n    hdiutil detach -force \"$MNT_ESD\"\n\texit 1\nfi\n\nSUPPORT_DIR=\"$SCRIPT_DIR/support\"\n\n# Add First Boot Package Install.pkg to the OS X installer\n\nFIRSTBOOT_PKG=\"$SUPPORT_DIR/First Boot Package Install.pkg\"\n\nif [[ -e \"$FIRSTBOOT_PKG\" ]]; then\n   msg_status \"$FIRSTBOOT_PKG detected. Proceeding...\"\nelse\n\tmsg_error \"$FIRSTBOOT_PKG not found! This is needed for the OS to install properly, exiting..\"\n\tmsg_error \"The script is expecting the following:\"\n\tmsg_error \"A. That a first boot installer package is stored in $SUPPORT_DIR.\"\n\tmsg_error \"B. That the first boot installer package is named as follows: First Boot Package Install.pkg\"\n\tmsg_status \"\"\t\n\tmsg_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.\"\n\tmsg_status \"This first boot package will automatically install all available Apple software updates following the OS installation, but provide no other customization.\"\n\tmsg_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.\"\n\tmsg_status \"\"\n\tmsg_status \"If you want customization, the first boot package can be generated by First Boot Package Install Generator.app,\"\n\tmsg_status \"which will generate a distribution-style flat package that can be used with $OSNAME installs.\"\n\tmsg_status \"\"\n\tmsg_status \"The instructions for using this tool to generate first boot packages are documented here:\"\n\tmsg_status \"https://github.com/rtrouton/First_Boot_Package_Install_Generator\"\n\texit 1\nfi\n\n# We'd previously mounted this to check versions\nhdiutil detach \"$MNT_BASE_SYSTEM\"\n\nBASE_SYSTEM_DMG_RW=\"$(/usr/bin/mktemp /tmp/vmware-apple-basesystem-rw.XXXX).dmg\"\n\nmsg_status \"Creating empty read-write DMG located at $BASE_SYSTEM_DMG_RW..\"\nhdiutil create -o \"$BASE_SYSTEM_DMG_RW\" -size 10g -layout SPUD -fs HFS+J\nhdiutil attach \"$BASE_SYSTEM_DMG_RW\" -mountpoint \"$MNT_BASE_SYSTEM\" -nobrowse -owners on\n\nmsg_status \"Restoring the BaseSystem to the read-write DMG using asr..\"\n\n# This asr restore is needed as of 10.11 DP7 and up. See\n# https://github.com/timsutton/osx-vm-templates/issues/40\n#\n# Note that when the restore completes, the volume is automatically re-mounted\n# into /Volumes instead of the previous mountpoint. It is also visible as the \n# \"-nobrowse\" option is not applied.\n\nasr restore --source \"$BASE_SYSTEM_DMG\" --target \"$MNT_BASE_SYSTEM\" --noprompt --noverify --erase\n\n# To fix the volume being visible when remounted, check for the new\n# volume which is mounted in /Volumes and unmount it.\n\nif [[ -e \"/Volumes/OS X Base System\" ]]; then\n   umount \"/Volumes/OS X Base System\"\nelif [[ -e \"/Volumes/Mac OS X Base System\" ]]; then\n   umount \"/Volumes/Mac OS X Base System\"\nfi\n\n# Remounting the disk image outside of /Volumes with the '-nobrowse' option.\n\nhdiutil attach \"$BASE_SYSTEM_DMG_RW\" -mountpoint \"$MNT_BASE_SYSTEM\" -nobrowse -owners on\n\nif [[ $DMG_OS_VERS_MAJOR -ge 9 ]]; then\n    BASESYSTEM_OUTPUT_IMAGE=\"$OUTPUT_DMG\"\n    PACKAGES_DIR=\"$MNT_BASE_SYSTEM/System/Installation/Packages\"\n\n    rm \"$PACKAGES_DIR\"\n\tmsg_status \"Moving 'Packages' directory from the ESD to BaseSystem..\"\n\tmv -v \"$MNT_ESD/Packages\" \"$MNT_BASE_SYSTEM/System/Installation/\"\n\n\t# This isn't strictly required for Mavericks, but Yosemite will consider the\n\t# installer corrupt if this isn't included, because it cannot verify BaseSystem's\n\t# consistency and perform a recovery partition verification\n\tmsg_status \"Copying in original BaseSystem dmg and chunklist..\"\n\tcp \"$MNT_ESD/BaseSystem.dmg\" \"$MNT_BASE_SYSTEM/\"\n\tcp \"$MNT_ESD/BaseSystem.chunklist\" \"$MNT_BASE_SYSTEM/\"\nelse\n    BASESYSTEM_OUTPUT_IMAGE=\"$MNT_ESD/BaseSystem.dmg\"\n    rm \"$BASESYSTEM_OUTPUT_IMAGE\"\n\tPACKAGES_DIR=\"$MNT_ESD/Packages\"\nfi\n\n# Adding a custom rc.cdrom.local that will automatically erase the VM's\n# boot drive. Also adding our auto-setup files: minstallconfig.xml and \n# OSInstall.collection\n\nmsg_status \"Adding automated components..\"\nCDROM_LOCAL=\"$MNT_BASE_SYSTEM/private/etc/rc.cdrom.local\"\necho \"diskutil eraseDisk jhfs+ \\\"Macintosh HD\\\" GPTFormat disk0\" > \"$CDROM_LOCAL\"\nchmod a+x \"$CDROM_LOCAL\"\nmkdir \"$PACKAGES_DIR/Extras\"\ncp \"$SUPPORT_DIR/minstallconfig.xml\" \"$PACKAGES_DIR/Extras/\"\ncp \"$SUPPORT_DIR/OSInstall.collection\" \"$PACKAGES_DIR/\"\ncp -r \"$FIRSTBOOT_PKG\" \"$PACKAGES_DIR/\"\nrm -rf \"$SUPPORT_DIR/tmp\"\n\nmsg_status \"Unmounting BaseSystem..\"\nhdiutil detach \"$MNT_BASE_SYSTEM\"\n\nif [ $DMG_OS_VERS_MAJOR -lt 9 ]; then\n\tmsg_status \"Pre-Mavericks we save back the modified BaseSystem to the root of the ESD.\"\n\thdiutil convert -format UDZO -o \"$MNT_ESD/BaseSystem.dmg\" \"$BASE_SYSTEM_DMG_RW\"\nfi\n\nmsg_status \"Unmounting..\"\nhdiutil detach \"$MNT_ESD\"\n\nmsg_status \"Converting to .dmg disk image..\"\n\nif [[ $DMG_OS_VERS_MAJOR -ge 9 ]]; then\n\tmsg_status \"On Mavericks and later, the entire modified BaseSystem is our output dmg.\"\n\thdiutil convert -format UDZO -o \"$OUTPUT_DMG\" \"$BASE_SYSTEM_DMG_RW\"\nelse\n\tmsg_status \"Pre-Mavericks we're modifying the original ESD file.\"\n\thdiutil convert -format UDZO -o \"$OUTPUT_DMG\" -shadow \"$SHADOW_FILE\" \"$ESD\"\nfi\n\nrm -rf \"$MNT_ESD\" \"$SHADOW_FILE\" \"$BASE_SYSTEM_DMG_RW\"\n\nif [[ $ISO = 1 ]]; then\n   OUTPUT_ISO=\"$OUT_DIR/${OSNAME}_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.iso\"\n   msg_status \"Converting to .iso disk image....\"\n   /usr/bin/hdiutil convert \"$OUTPUT_DMG\" -format UDTO -o \"$OUTPUT_ISO\"\n   /bin/mv $OUT_DIR/${OSNAME}_InstallESD_${DMG_OS_VERS}_${DMG_OS_BUILD}.iso.cdr \"$OUTPUT_ISO\"\nfi\n\nif [[ -n \"$SUDO_UID\" ]] && [[ -n \"$SUDO_GID\" ]]; then\n\tmsg_status \"Fixing permissions..\"\n\tchown -R $SUDO_UID:$SUDO_GID \"$OUT_DIR\"\nfi\n\nmsg_status \"Checksumming .dmg disk image..\"\nMD5=$(md5 -q \"$OUTPUT_DMG\")\nmsg_status \"MD5: $MD5\"\nmsg_status \"Built .dmg disk image is located at $OUTPUT_DMG.\"\n\nif [[ -f \"$OUTPUT_ISO\" ]]; then\n  msg_status \"Checksumming .iso disk image..\"\n  MD5=$(md5 -q \"$OUTPUT_ISO\")\n  msg_status \"MD5: $MD5\"\n  msg_status \"Built .iso disk image is located at $OUTPUT_ISO.\"\nfi\n\nmsg_status \"Build process finished.\""
  },
  {
    "path": "support/OSInstall.collection",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array>\n\t<string>/System/Installation/Packages/OSInstall.mpkg</string>\n\t<string>/System/Installation/Packages/OSInstall.mpkg</string>\n\t<string>/System/Installation/Packages/First Boot Package Install.pkg</string>\n</array>\n</plist>\n\n"
  },
  {
    "path": "support/minstallconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>InstallType</key>\n\t<string>automated</string>\n\t<key>Language</key>\n\t<string>en</string>\n\t<key>Package</key>\n\t<string>/System/Installation/Packages/OSInstall.collection</string>\n\t<key>Target</key>\n\t<string>/Volumes/Macintosh HD</string>\n\t<key>TargetName</key>\n\t<string>Macintosh HD</string>\n</dict>\n</plist>\n"
  }
]