packer { required_plugins { tart = { version = ">= 1.12.0" source = "github.com/cirruslabs/tart" } ansible = { version = "~> 1" source = "github.com/hashicorp/ansible" } } } source "tart-cli" "tart" { # You can find macOS IPSW URLs on various websites like https://ipsw.me/ # and https://www.theiphonewiki.com/wiki/Beta_Firmware/Mac/13.x from_ipsw = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-55833/C0830847-A2F8-458F-B680-967991820931/UniversalMac_13.6_22G120_Restore.ipsw" vm_name = "ventura-vanilla" cpu_count = 4 memory_gb = 8 disk_size_gb = 50 ssh_password = "admin" ssh_username = "admin" ssh_timeout = "120s" boot_command = [ # hello, hola, bonjour, etc. "", # Language: most of the times we have a list of "English"[1], "English (UK)", etc. with # "English" language already selected. If we type "english", it'll cause us to switch # to the "English (UK)", which is not what we want. To solve this, we switch to some other # language first, e.g. "Italiano" and then switch back to "English". We'll then jump to the # first entry in a list of "english"-prefixed items, which will be "English". # # [1]: should be named "English (US)", but oh well 🤷 "italianoenglish", # Select Your Country and Region "united states", # Written and Spoken Languages "", # Accessibility "", # Data & Privacy "", # Migration Assistant "", # Sign In with Your Apple ID "", # Are you sure you want to skip signing in with an Apple ID? "", # Terms and Conditions "", # I have read and agree to the macOS Software License Agreement "", # Create a Computer Account "adminadminadmin", # Enable Location Services "", # Are you sure you don't want to use Location Services? "", # Select Your Time Zone "UTC", # Analytics "", # Screen Time "", # Siri "", # Choose Your Look "", # Enable Voice Over "v", # Now that the installation is done, open "System Settings" "System Settings", # Navigate to "Sharing" "fsharing", # Navigate to "Screen Sharing" and enable it "", # Navigate to "Remote Login" and enable it "", # Open "Remote Login" details "", # Enable "Full Disk Access" "", # Click "Done" "", # Disable Voice Over "", ] // A (hopefully) temporary workaround for Virtualization.Framework's // installation process not fully finishing in a timely manner create_grace_time = "30s" // Keep the recovery partition, otherwise it's not possible to "softwareupdate" recovery_partition = "keep" } build { sources = ["source.tart-cli.tart"] provisioner "shell" { inline = [ // Enable passwordless sudo "echo admin | sudo -S sh -c \"mkdir -p /etc/sudoers.d/; echo 'admin ALL=(ALL) NOPASSWD: ALL' | EDITOR=tee visudo /etc/sudoers.d/admin-nopasswd\"", // Enable auto-login // // See https://github.com/xfreebird/kcpassword for details. "echo '00000000: 1ced 3f4a bcbc ba2c caca 4e82' | sudo xxd -r - /etc/kcpassword", "sudo defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser admin", // Disable screensaver at login screen "sudo defaults write /Library/Preferences/com.apple.screensaver loginWindowIdleTime 0", // Disable screensaver for admin user "defaults -currentHost write com.apple.screensaver idleTime 0", // Prevent the VM from sleeping "sudo systemsetup -setdisplaysleep Off 2>/dev/null", "sudo systemsetup -setsleep Off 2>/dev/null", "sudo systemsetup -setcomputersleep Off 2>/dev/null", // Launch Safari to populate the defaults "/Applications/Safari.app/Contents/MacOS/Safari &", "SAFARI_PID=$!", "disown", "sleep 30", "kill -9 $SAFARI_PID", // Enable Safari's remote automation "sudo safaridriver --enable", // Disable screen lock // // Note that this only works if the user is logged-in, // i.e. not on login screen. "sysadminctl -screenLock off -password admin", "defaults -currentHost write com.apple.screensaver idleTime 0" ] } provisioner "shell" { inline = [ # Install command-line tools "touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress", "softwareupdate --list | sed -n 's/.*Label: \\(Command Line Tools for Xcode-.*\\)/\\1/p' | xargs -I {} softwareupdate --install '{}'", "rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress", ] } provisioner "ansible" { playbook_file = "ansible/playbook-system-updater.yml" extra_arguments = [ "-vvv", ] ansible_env_vars = [ "ANSIBLE_TRANSPORT=paramiko", "ANSIBLE_HOST_KEY_CHECKING=False", ] use_proxy = false } }