#!/usr/bin/env bash # ## WizardKit: Live macOS Build Tool set -o errexit set -o errtrace set -o nounset set -o pipefail # Variables BASE_IMAGE="" HELP="" LINUX_DIR="linux" MACOS_DIR="macos" ROOT_DIR=".." STANDLONE="" TOOLS_TO_CHECK=(memtest mprime smc sysbench) # Usage function usage() { echo "Usage: build_macos [OPTIONS] " echo "" echo "Options:" echo " -h --help Show usage" exit "${1:-0}" } # Check arguments while :; do case "${1:-}" in -h|--help) HELP="True" ;; -s|--standalone) STANDALONE="True" ;; -hs|-sh) HELP="True" ;; *) if [[ ! "${1:-}" == "" ]]; then BASE_IMAGE="${1}" fi break ;; esac shift done # Safety Checks if [[ ! "${HELP:-}" == "" ]]; then usage fi if [[ ! "${STANDALONE:-}" == "" ]]; then echo "Building standalone image" fi if [[ "${BASE_IMAGE:-}" == "" ]]; then echo "No image specified" 1>&2 echo "" usage 1 elif [[ ! -f "${BASE_IMAGE:-}" ]]; then echo "Invalid image specified" 1>&2 echo "" usage 1 fi for tool in "${TOOLS_TO_CHECK[@]}"; do if [[ ! -e "/usr/local/bin/$tool" ]]; then echo "Missing tool(s) detected" echo " Installing dependencies in 30 seconds, enter CTRL+c to abort." sleep 30 "${MACOS_DIR}/install-deps" exit fi done # Load settings while read line; do if echo "$line" | grep -Eq "^\w+='"; then line="$(echo "$line" | sed -E 's/[\r\n]+//')" eval "$line" fi done < "$ROOT_DIR/scripts/wk/cfg/main.py" # Prep echo "Initializing..." IMAGE_DEV="$(hdiutil attach -mountpoint /Volumes/BaseSystem "${BASE_IMAGE}" -nobrowse | grep -Eo '(/dev/disk[0-9]+)\b')" OS_NAME="$(ls /Volumes/BaseSystem | grep -E 'OS X|macOS' | sed -E 's/Install (OS X|macOS) (.*)\.app/\2/')" OS_VERSION="$(defaults read /Volumes/BaseSystem/System/Library/CoreServices/SystemVersion ProductVersion)" OUT_NAME="${HOME}/Desktop/macWK ${OS_NAME} ($(date +"%Y-%m-%d"))" if [[ "${STANDALONE:-}" == "" ]]; then OUT_NAME="${OUT_NAME} (NoBoot)" fi TIMEZONE="$(grep -F LINUX_TIME_ZONE "${ROOT_DIR}/scripts/wk/cfg/main.py" | cut -d '=' -f 2 | sed "s/'//g")" WK_PATH="/Volumes/${KIT_NAME_SHORT}_UFD" # Convert to a 4 GB R/W image echo "Creating read-write copy of the ${OS_NAME} Base System image..." hdiutil create -srcdevice "${IMAGE_DEV}s1" -format UDSB "${OUT_NAME}.sparsebundle" hdiutil detach "${IMAGE_DEV}" hdiutil resize -size 4g "${OUT_NAME}.sparsebundle" WK_IMAGE_DEV="$(hdiutil attach "${OUT_NAME}.sparsebundle" -nobrowse | grep -Eo '(/dev/disk[0-9]+)\b')" if ! diskutil rename "OS X Base System" "${KIT_NAME_SHORT}_UFD"; then diskutil rename "macOS Base System" "${KIT_NAME_SHORT}_UFD" fi # Remove Install app echo "Removing Install app..." rm -R "${WK_PATH}"/Install*.app # Update Utilities menu echo "Updating Utilities menu..." if [[ "${OS_VERSION:0:5}" == "10.11" ]]; then cp -a "${MACOS_DIR}/El Capitan/Utilities.plist" "${WK_PATH}/System/Installation/CDIS/OS X Utilities.app/Contents/Resources/Utilities.plist" elif [[ "${OS_VERSION:0:5}" == "10.13" ]]; then cp -a "${MACOS_DIR}/High Sierra/Utilities.plist" "${WK_PATH}/System/Installation/CDIS/macOS Utilities.app/Contents/Resources/Utilities.plist" elif [[ "${OS_VERSION:0:5}" == "10.15" ]]; then cp -a "${MACOS_DIR}/Catalina/Utilities.plist" "${WK_PATH}/System/Installation/CDIS/macOS Utilities.app/Contents/Resources/Utilities.plist" fi # Dropbear (SSH) echo "Installing Dropbear..." mkdir -p "${WK_PATH}/etc/dropbear" for t in rsa dss ecdsa ed25519; do dropbearkey -t "${t}" -f "${WK_PATH}/etc/dropbear/dropbear_${t}_host_key" done ln -s /Volumes/RAM_Disk/.ssh "${WK_PATH}/var/root"/ cp -a "${LINUX_DIR}/authorized_keys" "${WK_PATH}/.authorized_keys" # Homebrew echo "Installing Hombrew..." mkdir -p "${WK_PATH}/usr/local/bin" ln -s python3 "${WK_PATH}/usr/local/bin/python" rsync -aS /opt/ "${WK_PATH}/opt"/ rsync -aS --exclude='.git*' /usr/local/{Cellar,Frameworks,Homebrew,bin,etc,include,lib,opt,sbin,share,var} "${WK_PATH}/usr/local"/ if [[ "${OS_VERSION:3:2}" -lt "15" ]]; then rsync -aS --exclude='*.git' /usr/local/libexec "${WK_PATH}/usr/local"/ fi # Fonts echo "Installing Fonts..." cp -a /Library/Fonts/Inconsolata*ttf "${WK_PATH}/System/Library/Fonts"/ # pipes-sh echo "Installing pipes.sh..." cp -a /usr/bin/tput "${WK_PATH}/usr/bin"/ # Terminal echo "Installing Terminal Preferences..." cp -a "${MACOS_DIR}/com.apple.Terminal.plist" "${WK_PATH}/var/root/Library/Preferences"/ # Timezones echo "Installing timezones..." if [[ "${OS_VERSION:3:2}" == "11" ]]; then rsync -aS /usr/share/zoneinfo/ "${WK_PATH}/usr/share/zoneinfo"/ ln -sf "/usr/share/zoneinfo/${TIMEZONE}" "${WK_PATH}/etc/localtime" elif [[ "${OS_VERSION:3:2}" -gt "11" ]]; then sudo mkdir -p "${WK_PATH}/var/db/timezone/zoneinfo" sudo rsync -aS /var/db/timezone/zoneinfo/ "${WK_PATH}/var/db/timezone/zoneinfo"/ ln -sf "/var/db/timezone/zoneinfo/${TIMEZONE}" "${WK_PATH}/etc/localtime" fi # zsh echo "Installing zsh..." cp -a /bin/zsh "${WK_PATH}/bin"/ cp -a "${MACOS_DIR}/zshenv" "${WK_PATH}/etc"/ rsync -aS /usr/lib/zsh "${WK_PATH}/usr/lib"/ rsync -aS /usr/share/zsh "${WK_PATH}/usr/share"/ rsync -aS /usr/local/share/zsh "${WK_PATH}/usr/local/share"/ sed -Ei '' 's!^(root.*)/bin/sh!\1/bin/zsh!' "${WK_PATH}/etc/passwd" # memtest sudo mv -nv "${WK_PATH}/usr/local/bin/memtest" "${WK_PATH}/usr/sbin"/ sudo chown 0:0 "${WK_PATH}/usr/sbin/memtest" sudo chmod 755 "${WK_PATH}/usr/sbin/memtest" # Misc cp -a "${LINUX_DIR}/known_networks" "${WK_PATH}/.known_networks" cp -a /usr/bin/rsync "${WK_PATH}/usr/bin"/ cp -a /usr/sbin/networksetup "${WK_PATH}/usr/sbin"/ cp -a "${MACOS_DIR}/aliases" "${WK_PATH}/.aliases" cp -a "${MACOS_DIR}/bashrc" "${WK_PATH}/etc/profile" cp -a "${MACOS_DIR}/vimrc" "${WK_PATH}/.vimrc" if [[ "${OS_VERSION:3:2}" == "11" ]]; then cp -a /usr/bin/grep "${WK_PATH}/usr/bin"/ cp -a /usr/bin/locale "${WK_PATH}/usr/bin"/ rsync -aS /usr/share/locale/ "${WK_PATH}/usr/share/locale"/ elif [[ "${OS_VERSION:3:2}" == "13" ]]; then cp -a /usr/lib/libexpat* "${WK_PATH}/usr/lib"/ fi # WizardKit echo "Installing WizardKit env..." touch "${WK_PATH}/.wk-live-macos" ln -s /Volumes/RAM_Disk/Logs "${WK_PATH}/var/root/Logs" cp -a "${LINUX_DIR}/profile_base/airootfs/etc/skel/.tmux.conf" "${WK_PATH}/etc/tmux.conf" rsync -aS /usr/bin/{env,killall} "${WK_PATH}/usr/bin"/ rsync -aS "${MACOS_DIR}/live-macos-startup" "${ROOT_DIR}/scripts/" "${WK_PATH}/usr/local/bin"/ if [[ -f "${ROOT_DIR}/images/macOS-${OS_VERSION:0:5}.jpg" ]]; then cp -a "${ROOT_DIR}/images/macOS-${OS_VERSION:0:5}.jpg" "${WK_PATH}/usr/local/wallpaper.jpg" else cp -a "${ROOT_DIR}/images/macOS.jpg" "${WK_PATH}/usr/local/wallpaper.jpg" fi # Unbless if [[ "${STANDALONE:-}" == "" ]]; then echo "Unblessing image..." sudo bless --unbless "${WK_PATH}" sudo bless --unbless "${WK_PATH}/System/Library/CoreServices" fi # Unmount sparsebundle hdiutil detach "${WK_IMAGE_DEV}" # Convert to compressed read-only image echo "Converting to read-only image..." hdiutil resize -sectors min "${OUT_NAME}.sparsebundle" hdiutil convert -format UDZO -o "${OUT_NAME}.dmg" "${OUT_NAME}.sparsebundle"