#!/bin/bash # Apple LaunchDaemon bootstrap before the guest .NET SDK exists. # Runs only inside the isolated owned VM; installs CLT and expands the pinned SDK. set -u PATH="/usr/bin:/bin:/usr/sbin:/sbin" export PATH PROOF_TOKEN="${1:-}" STATE_DIR="/Volumes/installstate" WORK="/private/var/tmp/meeting-assistant-native-$PROOF_TOKEN" [[ "$PROOF_TOKEN" =~ ^[0-9a-f]{32}$ ]] || exit 1 [ "$(cat "$STATE_DIR/run.owner" 2>/dev/null)" = "$PROOF_TOKEN" ] || exit 1 exec >> "$STATE_DIR/firstboot.log" 2>&1 phase() { printf '{"token":"%s","phase":"%s","updatedUtc":"%s"}\n' "$PROOF_TOKEN" "$1" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$STATE_DIR/guest-phase.json.tmp" mv -f "$STATE_DIR/guest-phase.json.tmp" "$STATE_DIR/guest-phase.json" } fail() { printf '[firstboot] ERROR: %s\n' "$1"; phase bootstrap-failed; exit 1; } require_installed_macos_version() { # Numeric sw_vers product release with a major version of at least 14. [[ "${1:-}" =~ ^(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,})\.[0-9]+(\.[0-9]+)?$ ]] } phase toolchain-installing echo '[firstboot] verifying installed OS, APFS and owned physical store' uname -a; id installed_version=$(/usr/bin/sw_vers -productVersion) || fail installed_os_version_failed require_installed_macos_version "$installed_version" || fail installed_macos_14_or_newer_required printf '[firstboot] installed macOS version=%s\n' "$installed_version" [ "$(id -u)" = 0 ] && [ "$(uname -m)" = x86_64 ] || fail wrong_guest_platform /usr/sbin/diskutil info -plist / > "$STATE_DIR/installed-root.plist" || fail root_diskutil_failed [ "$(/usr/libexec/PlistBuddy -c 'Print :FilesystemType' "$STATE_DIR/installed-root.plist")" = apfs ] || fail root_is_not_installed_apfs container=$(/usr/libexec/PlistBuddy -c 'Print :APFSContainerReference' "$STATE_DIR/installed-root.plist") || fail root_container_missing /usr/sbin/diskutil apfs list -plist > "$STATE_DIR/apfs-containers.plist" || fail apfs_list_failed index=0 physical="" while reference=$(/usr/libexec/PlistBuddy -c "Print :Containers:$index:ContainerReference" "$STATE_DIR/apfs-containers.plist" 2>/dev/null); do if [ "$reference" = "$container" ]; then [ -z "$physical" ] || fail ambiguous_root_containers physical=$(/usr/libexec/PlistBuddy -c "Print :Containers:$index:PhysicalStores:0:DeviceIdentifier" "$STATE_DIR/apfs-containers.plist") || fail physical_store_missing /usr/libexec/PlistBuddy -c "Print :Containers:$index:PhysicalStores:1" "$STATE_DIR/apfs-containers.plist" >/dev/null 2>&1 && fail multiple_physical_stores fi index=$((index + 1)) done [[ "$physical" =~ ^disk[0-9]+s[0-9]+$ ]] || fail invalid_physical_store /usr/sbin/diskutil info -plist "/dev/$physical" > "$STATE_DIR/physical-store.plist" || fail physical_store_info_failed whole=$(/usr/libexec/PlistBuddy -c 'Print :ParentWholeDisk' "$STATE_DIR/physical-store.plist") || fail physical_parent_missing . "$STATE_DIR/macos-native-disk-guard.sh" verify_owned_disk "/dev/$whole" "$STATE_DIR" "$PROOF_TOKEN" || fail installed_root_is_not_the_owned_64g_disk # The phase has an independent 30-minute watchdog; host outer deadline is 180 minutes. parent=$$ ( trap 'kill "$sleeper" 2>/dev/null || :; exit 0' TERM INT # Toolchain watchdog: 30 minutes, also bounded by the host's 172-minute total. sleep 1800 & sleeper=$!; wait "$sleeper"; kill -TERM "$parent" 2>/dev/null || : ) & watchdog=$! clt_marker="/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress" trap 'rm -f "$clt_marker"; kill -TERM "$watchdog" 2>/dev/null || :; wait "$watchdog" 2>/dev/null || :' EXIT trap 'fail toolchain_deadline_or_cancellation' TERM INT [ ! -e "$WORK" ] || fail guest_work_directory_already_exists mkdir -p "$WORK" || fail guest_work_directory_failed printf '%s\n' "$PROOF_TOKEN" > "$WORK/run.owner" || fail guest_work_owner_failed free_kib=$(df -Pk "$WORK" | awk 'NR==2 {print $4}') [[ "$free_kib" =~ ^[0-9]+$ ]] && (( free_kib >= 8 * 1024 * 1024 )) || fail insufficient_existing_guest_free_space echo '[firstboot] installing a compatible Apple CLT catalog entry without a GUI' touch "$clt_marker" || fail clt_marker_failed /usr/sbin/softwareupdate -l > "$STATE_DIR/clt-catalog.log" 2>&1 || fail clt_catalog_failed label=$(grep -B 1 -E 'Command Line Tools' "$STATE_DIR/clt-catalog.log" | awk -F'*' '/^ *\*/ {print $2}' | sed -e 's/^ *Label: //' -e 's/^ *//' | sort -V | tail -n 1) [ -n "$label" ] || fail no_compatible_headless_clt_label printf '[firstboot] selected CLT: %s\n' "$label" /usr/sbin/softwareupdate -i "$label" > "$STATE_DIR/clt-install.log" 2>&1 || fail clt_install_failed /usr/bin/xcode-select --switch /Library/Developer/CommandLineTools || fail clt_switch_failed /usr/sbin/pkgutil --pkg-info=com.apple.pkg.CLTools_Executables || fail clt_receipt_failed /usr/bin/xcrun --find swiftc || fail swiftc_missing /usr/bin/xcrun swiftc --version || fail swiftc_version_failed { /usr/bin/xcrun --sdk macosx --show-sdk-version && /usr/bin/xcrun --sdk macosx --show-sdk-path } > "$STATE_DIR/clt-sdk.log" 2>&1 || fail clt_sdk_identity_failed printf 'import AppKit\nimport AVFoundation\nimport ScreenCaptureKit\nimport EventKit\nimport WebKit\nprint("native SDK ready")\n' > "$WORK/toolchain-smoke.swift" /usr/bin/xcrun swiftc -target x86_64-apple-macos13.0 "$WORK/toolchain-smoke.swift" -o "$WORK/toolchain-smoke" || fail native_framework_compile_failed "$WORK/toolchain-smoke" || fail native_framework_execution_failed rm -f "$clt_marker" echo '[firstboot] validating and expanding the pinned .NET SDK on owned APFS' expected_sdk=33401b4a2da8554e3306db6072ea8569d9fcc608509c271e0aa4b39e7cc432da3631f14e7e1e2445d67d72550d18ce44a8bbd2382a756867ad2edab6b1c963c0 actual_sdk=$(shasum -a 512 "$STATE_DIR/sdk.tar.gz" | awk '{print $1}') [ "$actual_sdk" = "$expected_sdk" ] || fail sdk_hash_mismatch mkdir "$WORK/dotnet" || fail sdk_directory_failed tar -xzf "$STATE_DIR/sdk.tar.gz" -C "$WORK/dotnet" || fail sdk_extract_failed [ "$("$WORK/dotnet/dotnet" --version)" = 10.0.401 ] || fail sdk_version_mismatch # Guest C# owns build/test deadlines from this point; stop the CLT-only watchdog. kill -TERM "$watchdog" 2>/dev/null || : wait "$watchdog" 2>/dev/null || : trap - TERM INT "$WORK/dotnet/dotnet" run --file "$STATE_DIR/MacOsNativeGuest.cs" -- --run --state "$STATE_DIR" --work "$WORK" result=$? (( result == 0 )) || fail native_tests_failed exit 0