08. Developer Reference - setup-your-mac/Setup-Your-Mac GitHub Wiki
Developer Reference
Complete technical reference for Setup Your Mac (v1.15.1) including function documentation, troubleshooting procedures, and implementation details.
Overview
This reference is designed for developers, advanced administrators, and troubleshooting scenarios. It covers:
- Script Architecture - High-level technical overview
- Function Reference - All 40+ functions with line numbers and usage
- Troubleshooting Guide - Common issues and debug procedures
- Debug and Development - Development tools and techniques
Script Architecture
Understanding the Setup Your Mac script structure and execution flow.
Technical Overview
The Setup Your Mac script (v1.15.1) is a comprehensive 3,547-line Bash script organized into distinct functional areas:
- Language: Bash with POSIX compliance
- Size: 3,547 lines of code
- Functions: 40+ discrete functions for specific operations
- Dependencies: swiftDialog 2.5.0+, Jamf Pro, macOS 12+
Core Function Categories
System Utilities (8 functions)
- User management and session handling
- System validation and requirements checking
- Resource monitoring and disk space calculation
- Power management and AC adapter validation
Dialog Interface (6 functions)
- swiftDialog command processing and updates
- Real-time progress indication
- User input collection and validation
- Multi-dialog coordination
Policy Engine (4 functions)
- Jamf Pro policy execution with error handling
- Validation framework (Local, Remote, None methods)
- Policy result processing and reporting
- Retry logic and failure management
Network Operations (3 functions)
- Network quality testing using macOS networkQuality tool
- Download time estimation with configurable accuracy
- Bandwidth-aware configuration recommendations
Configuration Management (2 functions)
- JSON parsing using JavaScript for Automation (JXA)
- Dynamic policy configuration selection
- Parameter inheritance and override handling
Logging System (12 functions)
- Multi-level logging with timestamps
- Component-specific log prefixes
- Debug mode integration
- Log rotation and management
Execution Flow
- Pre-flight Checks - System validation, user session, dependencies
- Configuration Loading - Parameter processing, JSON parsing
- Welcome Dialog - User input collection, network testing
- Policy Execution - Sequential policy processing with validation
- Progress Tracking - Real-time dialog updates, error handling
- Completion - Final validation, cleanup, completion actions
Data Flow Architecture
Jamf Pro Parameters → Script Variables → JSON Configuration → Dialog Interface
↓ ↓ ↓
Policy Execution ← Validation Engine ← Progress Tracking
↓
Logging System → Webhook Notifications → Completion Actions
Function Reference
Complete documentation of all functions with line numbers, parameters, and usage examples.
Logging Functions
updateScriptLog() - Line 192
Purpose: Central logging function that writes timestamped entries to the script log
Parameters:
$1
- Log message text
Usage:
updateScriptLog "Setup process started"
updateScriptLog "Policy execution completed: ${policyName}"
Output Format:
sym (1.15.1): 2024-06-27 14:30:15 - Setup process started
preFlight() - Line 196
Purpose: Logs pre-flight check messages with standardized prefix
Parameters:
$1
- Pre-flight check message
Usage:
preFlight "Checking script environment"
preFlight "Validating user session"
Output:
[PRE-FLIGHT] Checking script environment
error() - Line 208
Purpose: Logs error messages with ERROR prefix
Parameters:
$1
- Error message
Usage:
error "Failed to connect to Jamf Pro server"
error "swiftDialog not found at expected path"
fatal() - Line 212
Purpose: Logs fatal error message and exits script with code 1
Parameters:
$1
- Fatal error message
Usage:
fatal "Critical dependency missing, cannot continue"
info() - Line 217
Purpose: Logs informational messages
Parameters:
$1
- Information message
Usage:
info "Policy execution successful"
info "Network quality test completed"
Specialized Logging Functions
logComment()
(Line 200) - General comments with indentationwelcomeDialog()
(Line 204) - Welcome dialog operationsupdateSetupYourMacDialog()
(Line 221) - Main dialog operationsupdateFailureDialog()
(Line 225) - Failure dialog operationsupdateSuccessDialog()
(Line 229) - Success messagesfinaliseUserExperience()
(Line 233) - User experience finalizationcompletionActionOut()
(Line 237) - Completion actionsquitOut()
(Line 241) - Script termination
System Utility Functions
runAsUser() - Line 259
Purpose: Executes commands as the logged-in user using launchctl
Parameters:
$1
- Command to execute
Usage:
runAsUser "open '/Applications/Self Service.app'"
runAsUser "defaults write com.company.app preference value"
Implementation:
Uses launchctl asuser
to run commands in the user's session context.
calculateFreeDiskSpace() - Line 273
Purpose: Calculates and formats available disk space
Returns: Available disk space in human-readable format
Usage:
freeDiskSpace=$(calculateFreeDiskSpace)
updateScriptLog "Available disk space: ${freeDiskSpace}"
Output Examples:
45.2 GB available
1.2 TB available
currentLoggedInUser() - Line 1446
Purpose: Determines the current logged-in user
Returns: Username of the currently logged-in user
Usage:
loggedInUser=$(currentLoggedInUser)
info "Current user: ${loggedInUser}"
Implementation:
Uses stat -f%Su /dev/console
for reliable user detection.
acPowerCheck() - Line 1597
Purpose: Verifies AC power connection before proceeding
Behavior:
- Checks power adapter connection status
- Displays dialog if running on battery power
- Allows user to continue or connect power
Usage:
acPowerCheck
toggleJamfLaunchDaemon() - Line 1662
Purpose: Manages Jamf binary check-in daemon
Parameters:
$1
- Action: "disable" or "enable"
Usage:
toggleJamfLaunchDaemon "disable" # Disable during setup
toggleJamfLaunchDaemon "enable" # Re-enable after setup
killProcess() - Line 859
Purpose: Terminates specified processes safely
Parameters:
$1
- Process name or PID
Usage:
killProcess "Self Service"
killProcess "Dialog"
Dialog Interface Functions
dialogUpdateWelcome() - Line 291
Purpose: Updates Welcome dialog with commands
Parameters:
$1
- Dialog command
Usage:
dialogUpdateWelcome "progresstext: Initializing setup..."
dialogUpdateWelcome "button1text: Continue"
dialogUpdateSetupYourMac() - Line 301
Purpose: Updates Setup Your Mac dialog with commands
Parameters:
$1
- Dialog command
Usage:
dialogUpdateSetupYourMac "listitem: Installing Microsoft Office"
dialogUpdateSetupYourMac "progress: 45"
dialogUpdateFailure() - Line 312
Purpose: Updates Failure dialog with commands
Parameters:
$1
- Dialog command
Usage:
dialogUpdateFailure "message: Setup encountered an error"
dialogUpdateFailure "icon: /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns"
welcomeDialogInfoboxAnimation() - Line 1013
Purpose: Displays animated clock in Welcome dialog infobox
Behavior:
- Shows current time with updating display
- Provides visual feedback during network testing
- Runs in background process
Usage:
welcomeDialogInfoboxAnimation &
setupYourMacDialogInfoboxAnimation() - Line 1036
Purpose: Displays animated clock in Setup Your Mac dialog infobox
Similar to welcome animation but for main setup dialog
Policy Management Functions
run_jamf_trigger() - Line 485
Purpose: Executes Jamf Pro policy triggers with debug mode handling
Parameters:
$1
- Policy trigger name$2
- Policy display name
Usage:
run_jamf_trigger "install-office" "Microsoft Office"
run_jamf_trigger "install-chrome" "Google Chrome"
Features:
- Respects debug mode settings
- Handles dry-run scenarios
- Provides execution timing
- Captures exit codes
confirmPolicyExecution() - Line 512
Purpose: Determines whether to execute policies based on validation criteria
Parameters:
$1
- Policy trigger$2
- Validation method$3
- Validation path/criteria
Returns:
"true"
- Policy should be executed"false"
- Policy should be skipped
Usage:
shouldRun=$(confirmPolicyExecution "install-office" "Local" "/Applications/Microsoft Word.app")
if [ "${shouldRun}" == "true" ](/setup-your-mac/Setup-Your-Mac/wiki/-"${shouldRun}"-==-"true"-); then
run_jamf_trigger "install-office" "Microsoft Office"
fi
validatePolicyResult() - Line 586
Purpose: Validates policy execution results using multiple validation methods
Parameters:
$1
- Policy trigger$2
- Validation method ("Local", "Remote", "None")$3
- Validation criteria
Returns:
"Success"
- Validation passed"Failed"
- Validation failed
Validation Methods:
Local Validation
- File/application existence
- Process verification
- Built-in validations (FileVault, etc.)
Remote Validation
- Network-based checks
- API endpoint validation
- Service connectivity
Usage:
result=$(validatePolicyResult "install-office" "Local" "/Applications/Microsoft Word.app")
Network and Configuration Functions
checkNetworkQualityConfigurations() - Line 1058
Purpose: Tests network quality and estimates download times for all configurations
Behavior:
- Uses macOS
networkQuality
tool - Calculates download times based on configuration sizes
- Updates Welcome dialog with estimates
- Applies correction coefficient for accuracy
Usage:
checkNetworkQualityConfigurations
Output Example:
Configuration estimates:
Required: 12 minutes
Recommended: 22 minutes
Complete: 38 minutes
checkNetworkQualityCatchAllConfiguration() - Line 1122
Purpose: Tests network quality for catch-all configuration
Similar to main function but focused on default configuration
policyJSONConfiguration() - Line 2273
Purpose: Selects appropriate policy JSON configuration based on user selection
Parameters:
$1
- Configuration choice ("Required", "Recommended", "Complete")
Returns: Sets policyJSON
variable with selected configuration
Usage:
policyJSONConfiguration "${configurationChoice}"
JSON Processing Functions
get_json_value() - Line 460
Purpose: Parses JSON values using osascript and JavaScript
Parameters:
$1
- JSON string$2
- Key path (e.g., "key.subkey")
Returns: Extracted value from JSON
Usage:
username=$(get_json_value "${jsonData}" "username")
email=$(get_json_value "${jsonData}" "contact.email")
Implementation: Uses JavaScript for Automation (JXA) for reliable JSON parsing.
get_json_value_welcomeDialog() - Line 472
Purpose: Specialized JSON parser for Welcome dialog results
Parameters:
$1
- Welcome dialog JSON response$2
- Field name
Usage:
assetTag=$(get_json_value_welcomeDialog "${welcomeResults}" "Asset Tag")
building=$(get_json_value_welcomeDialog "${welcomeResults}" "Building")
Core Workflow Functions
finalise() - Line 323
Purpose: Main completion function that handles success/failure scenarios
Behavior:
- Evaluates overall setup success/failure
- Displays appropriate completion dialogs
- Triggers webhook notifications
- Manages cleanup operations
Usage: Called automatically at script completion.
completionAction() - Line 879
Purpose: Handles various completion actions (restart, shutdown, logout, etc.)
Parameters:
$1
- Completion action type
Supported Actions:
wait
- Wait for user actionsleep
- Wait specified timeShut Down
/Shut Down Attended
/Shut Down Confirm
Restart
/Restart Attended
/Restart Confirm
Log Out
/Log Out Attended
/Log Out Confirm
Usage:
completionAction "Restart Attended"
completionAction "sleep 30"
quitScript() - Line 1345
Purpose: Clean exit function that removes temporary files and handles completion actions
Parameters:
$1
- Exit code (optional)
Behavior:
- Removes temporary command files
- Kills background processes
- Calls completion action
- Exits with specified code
Usage:
quitScript "0" # Successful exit
quitScript "1" # Error exit
Installation and Validation Functions
dialogInstall() - Line 1719
Purpose: Downloads and installs swiftDialog if needed
Behavior:
- Checks for existing swiftDialog installation
- Downloads latest version if missing or outdated
- Verifies installation success
- Sets appropriate permissions
Usage:
dialogInstall
dialogCheck() - Line 1764
Purpose: Validates swiftDialog installation and version requirements
Returns:
"0"
- swiftDialog available and compatible"1"
- swiftDialog missing or incompatible
Usage:
if ! dialogCheck; then
fatal "swiftDialog installation failed"
fi
Communication Functions
webHookMessage() - Line 1176
Purpose: Sends success/failure notifications to Microsoft Teams or Slack
Parameters:
$1
- Message type ("success" or "failure")
Features:
- Auto-detects webhook platform (Teams vs Slack)
- Formats messages appropriately for each platform
- Includes system information and user details
- Provides action buttons for support
Usage:
webHookMessage "success"
webHookMessage "failure"
Microsoft Teams Format:
- Adaptive Card with rich formatting
- Computer details and user information
- Action buttons for Jamf Pro record
Slack Format:
- Block-based message layout
- Formatted text with computer details
- Interactive elements where supported
Debug and Development Functions
outputLineNumberInVerboseDebugMode() - Line 249
Purpose: Outputs line numbers in verbose debug mode
Usage:
outputLineNumberInVerboseDebugMode
Behavior:
- Only active when
debugMode="verbose"
- Shows current line number in script execution
- Helps with troubleshooting and development
Output Example:
# Line 1234: Policy execution starting
Function Usage Patterns
Standard Policy Execution
# Check if policy should run
if confirmPolicyExecution "${trigger}" "${validation}" "${path}"; then
# Execute the policy
run_jamf_trigger "${trigger}" "${displayName}"
# Validate the result
result=$(validatePolicyResult "${trigger}" "${validation}" "${path}")
if [ "${result}" == "Success" ](/setup-your-mac/Setup-Your-Mac/wiki/-"${result}"-==-"Success"-); then
updateSetupYourMacDialog "listitem: ${displayName}: Complete"
else
updateSetupYourMacDialog "listitem: ${displayName}: Failed"
fi
fi
Dialog Update Sequence
# Update progress
dialogUpdateSetupYourMac "progress: ${currentProgress}"
# Update current item
dialogUpdateSetupYourMac "progresstext: Installing ${appName}..."
# Update list item status
dialogUpdateSetupYourMac "listitem: ${appName}: Complete"
Error Handling Pattern
if ! someOperation; then
error "Operation failed: ${operation}"
dialogUpdateFailure "message: Setup encountered an error"
quitScript "1"
fi
Troubleshooting Guide
Comprehensive troubleshooting procedures for Setup Your Mac deployment and operational issues.
Common Error Scenarios
swiftDialog Not Found
Error Message: dialog: command not found
or swiftDialog binary not found
Symptoms:
- Script fails to start
- No dialogs appear
- Error in script log about missing dialog binary
Causes:
- swiftDialog not installed
- Incorrect swiftDialog version
- Corrupted swiftDialog installation
Solutions:
-
Automatic Installation:
# Script will attempt automatic download # Check script log for download progress tail -f /var/log/setup-your-mac.log
-
Manual Installation:
# Download latest swiftDialog curl -L "https://github.com/swiftDialog/swiftDialog/releases/latest/download/dialog-2.5.0.pkg" -o /tmp/dialog.pkg installer -pkg /tmp/dialog.pkg -target /
-
Version Verification:
/usr/local/bin/dialog --version # Should return 2.5.0.4768 or later
Policy Execution Failures
Error Message: Policy execution failed
or Jamf binary not responding
Symptoms:
- Policies don't execute
- Progress bar stuck
- Applications not installing
Troubleshooting Steps:
-
Check Jamf Binary:
/usr/local/bin/jamf checkJSSConnection /usr/local/bin/jamf policy -event install-office -verbose
-
Verify Policy Configuration:
- Policy has Custom Trigger
- Policy is enabled
- Scope includes target computers
- Frequency set to "Ongoing"
-
Check Network Connectivity:
curl -I https://your-jamf-server.com ping your-jamf-server.com
-
Review Policy Logs:
tail -f /var/log/jamf.log
Network Quality Test Failures
Error Message: networkQuality command failed
or Download estimation unavailable
Symptoms:
- No download time estimates
- Script hangs during network testing
- Welcome dialog shows "Calculating..."
Solutions:
-
Check networkQuality Availability:
# macOS 12+ required which networkQuality networkQuality -v
-
Disable Network Testing:
# In script configuration configurationDownloadEstimation="false"
-
Manual Network Test:
networkQuality -s -v
Debug Mode Usage
Debug Mode Options
Verbose Mode (Recommended)
Setting: debugMode="verbose"
Features:
- Detailed logging with line numbers
- No sleep delays
- Full command output
- Real-time progress tracking
Usage:
# Set in Jamf Pro parameter 5
debugMode="verbose"
# View logs in real-time
tail -f /var/log/setup-your-mac.log
True Debug Mode
Setting: debugMode="true"
Features:
- Basic debug output
- 3-second sleep delays between actions
- Policy execution simulation
- User interaction delays
Best For:
- Step-by-step execution review
- User training scenarios
- Demonstration purposes
Standard Mode
Setting: debugMode="false"
Features:
- Standard operation
- Minimal logging
- Production performance
- Normal execution timing
Debug Output Examples
Verbose Mode Output:
sym (1.15.1): 2024-06-27 14:30:15 - # Line 1234: Starting policy execution
[SETUP YOUR MAC DIALOG] listitem: Microsoft Office: Pending
[INFO] Policy trigger: install-office
# Line 1245: Executing jamf policy
[SETUP YOUR MAC DIALOG] listitem: Microsoft Office: Complete
Debug Mode Output:
[DEBUG] Sleeping for 3 seconds...
[INFO] Would execute: jamf policy -event install-office
[DEBUG] Simulating policy execution
Log Analysis Tips
-
Filter by Component:
grep "\[ERROR\]" /var/log/setup-your-mac.log grep "\[PRE-FLIGHT\]" /var/log/setup-your-mac.log grep "Policy execution" /var/log/setup-your-mac.log
-
Time-based Analysis:
grep "$(date '+%Y-%m-%d')" /var/log/setup-your-mac.log
-
Follow Progress:
tail -f /var/log/setup-your-mac.log | grep "SETUP YOUR MAC"
Dialog and User Interface Issues
Dialog Not Appearing
Symptoms:
- Script runs but no dialog shows
- Process runs in background
- No user interaction possible
Troubleshooting:
-
Check User Session:
# Verify user is logged in stat -f%Su /dev/console # Check for console user ls -la /dev/console
-
Verify Dialog Process:
ps aux | grep dialog
-
Test Dialog Manually:
sudo -u "$loggedInUser" /usr/local/bin/dialog --message "Test dialog"
Dialog Freezing or Unresponsive
Symptoms:
- Dialog appears but doesn't respond
- Progress bar not updating
- Buttons don't work
Solutions:
-
Kill Existing Dialogs:
killall Dialog 2>/dev/null
-
Check Command File:
# Verify command file exists and is writable ls -la /var/tmp/dialog.log
-
Restart Dialog:
# Script will automatically restart dialog process
Progress Bar Issues
Symptoms:
- Progress bar not advancing
- Incorrect progress percentages
- Progress bar jumping erratically
Common Causes:
- Policy count mismatch
- Invalid progress calculations
- Multiple dialog instances
Fixes:
-
Verify Policy Count:
# Check that policy array matches actual policies echo "${policyJSON}" | jq '. | length'
-
Reset Progress:
dialogUpdateSetupYourMac "progress: reset"
Welcome Dialog User Input Issues
Symptoms:
- Fields not pre-populating
- Validation errors
- Dropdown menus empty
Solutions:
-
Check Field Configuration:
# Verify prompt variables are set correctly echo "Username prompt: ${promptForUsername}" echo "Buildings list: ${buildingsList}"
-
Validate JSON Syntax:
# Test JSON generation echo "${welcomeJSON}" | jq .
-
Review Field Dependencies:
- Email requires
emailEnding
variable - Dropdowns require populated list variables
- Pre-fill options require current user data
- Email requires
Network and Connectivity Issues
Download Failures
Symptoms:
- Policies fail during download phase
- Large applications not installing
- Intermittent connection issues
Troubleshooting:
-
Check Available Bandwidth:
networkQuality -s
-
Test Direct Downloads:
curl -I "https://your-distribution-point.com/package.pkg"
-
Verify DNS Resolution:
nslookup your-jamf-server.com dig your-jamf-server.com
Webhook Notification Failures
Symptoms:
- Teams/Slack notifications not appearing
- Webhook URL errors in logs
- Authentication failures
Solutions:
-
Test Webhook URL:
curl -X POST "${webhookURL}" \ -H "Content-Type: application/json" \ -d '{"text": "Test message"}'
-
Verify URL Format:
- Teams:
https://outlook.office.com/webhook/...
- Slack:
https://hooks.slack.com/services/...
- Teams:
-
Check Webhook Permissions:
- Verify webhook is enabled
- Confirm channel permissions
- Test with simple message
Proxy and Firewall Issues
Symptoms:
- Connection timeouts
- SSL certificate errors
- Blocked downloads
Solutions:
-
Configure Proxy Settings:
# Check system proxy settings networksetup -getwebproxy "Wi-Fi" networksetup -getsecurewebproxy "Wi-Fi"
-
Test Connectivity:
curl -v "https://github.com/swiftDialog/swiftDialog/releases" curl -v "https://your-jamf-server.com"
-
SSL Certificate Issues:
# Test SSL connection openssl s_client -connect your-jamf-server.com:443
Policy and Configuration Problems
Policy Validation Failures
Symptoms:
- Applications install but show as failed
- Validation timeouts
- Inconsistent validation results
Common Validation Issues:
-
File Path Validation:
# Common incorrect paths /Applications/App Name.app # Correct /Applications/App Name.app/ # Incorrect (trailing slash) /Applications/App Name # Incorrect (missing .app)
-
Process Validation:
# Check if process is running pgrep -f "Application Name"
-
Remote Validation:
# Test remote validation endpoint curl -s "https://validation-endpoint.com/check"
Configuration Selection Issues
Symptoms:
- Wrong configuration selected
- Configuration dropdown empty
- Policies don't match configuration
Solutions:
-
Verify Configuration Names:
echo "Config 1: ${configurationOneName}" echo "Config 2: ${configurationTwoName}" echo "Config 3: ${configurationThreeName}"
-
Check Policy JSON:
# Validate JSON syntax echo "${policyJSONConfiguration1}" | jq .
-
Review Configuration Logic:
- Ensure configuration names match dropdown options
- Verify policy arrays are properly defined
- Check for typos in configuration variables
Asset Tag and Computer Naming Issues
Symptoms:
- Computer name not updating
- Asset tag not set in Jamf Pro
- Inventory update failures
Troubleshooting:
-
Check Recon Execution:
/usr/local/bin/jamf recon -verbose
-
Verify Computer Name Settings:
# Check current computer name scutil --get ComputerName scutil --get LocalHostName
-
Test Manual Updates:
# Manual inventory update /usr/local/bin/jamf recon -assetTag "ABC123"
Performance and Resource Issues
High CPU Usage
Symptoms:
- System sluggish during setup
- Fans running high
- Dialog responsiveness poor
Causes:
- Multiple policy executions
- Large file downloads
- Background processes
Solutions:
-
Monitor Resource Usage:
top -o cpu | grep -E "(jamf|dialog|installer)"
-
Stagger Policy Execution:
- Add delays between policies
- Reduce concurrent operations
- Optimize policy order
-
Check Available Resources:
# Memory usage vm_stat # Disk space df -h
Disk Space Issues
Symptoms:
- Installation failures
- Download errors
- System warnings
Solutions:
-
Check Available Space:
df -h / # Minimum 10GB recommended for setup
-
Clean Temporary Files:
# Clear download cache rm -rf /Library/Application\ Support/JAMF/Downloads/* # Clear system caches rm -rf /private/var/folders/*/*/C/com.apple.installer*
-
Monitor Disk Usage:
du -sh /Applications/*
Memory Issues
Symptoms:
- System slowdown
- Application crashes
- Dialog freezing
Solutions:
-
Check Memory Pressure:
memory_pressure
-
Reduce Memory Usage:
- Close unnecessary applications
- Restart before setup
- Disable background processes
Pre-flight Check Failures
Operating System Version Issues
Symptoms:
- Script won't start
- OS version warnings
- Compatibility errors
Solutions:
-
Check OS Requirements:
sw_vers -productVersion # Minimum: macOS 12.0 for swiftDialog
-
Adjust Version Requirements:
# Modify requiredMinimumBuild parameter requiredMinimumBuild="23F" # For macOS 14.5
Setup Assistant Not Complete
Symptoms:
- Script exits immediately
- Setup Assistant still running
- User session not established
Solutions:
-
Check Setup Assistant Status:
ps aux | grep "Setup Assistant"
-
Wait for Completion:
- Script will wait for Setup Assistant
- Monitor setup progress
- Ensure user completes initial setup
Power Management Issues
Symptoms:
- AC power warnings
- System sleep during setup
- Power state conflicts
Solutions:
-
Check Power Status:
pmset -g batt
-
Disable Sleep:
# Script automatically uses caffeinate # Manual override if needed caffeinate -d -i -m -s &
Permission Issues
Symptoms:
- Access denied errors
- File creation failures
- Command execution blocked
Solutions:
-
Verify Script Execution:
# Must run as root whoami # Should return: root
-
Check File Permissions:
ls -la /var/tmp/ ls -la /usr/local/bin/dialog
Recovery and Cleanup Procedures
Emergency Cleanup
When to Use: Script crashed, system in unknown state, partial installation
Steps:
-
Kill All Processes:
killall Dialog 2>/dev/null killall caffeinate 2>/dev/null pkill -f "Setup Your Mac"
-
Remove Temporary Files:
rm -f /var/tmp/dialog.log rm -f /var/tmp/welcome.log rm -f /var/tmp/failure.log
-
Re-enable Jamf Daemon:
launchctl load /Library/LaunchDaemons/com.jamfsoftware.jamf.daemon.plist
Reset User Data
Purpose: Clear user input data and start fresh
Steps:
# Remove user defaults
sudo -u "$loggedInUser" defaults delete com.company.setupmac 2>/dev/null
# Clear cached data
rm -rf /var/tmp/sym-*
Partial Installation Recovery
Symptoms: Some applications installed, some failed
Recovery Strategy:
-
Identify Completed Policies:
# Check application installations ls /Applications/ | grep -E "(Office|Chrome|Adobe)"
-
Create Minimal Configuration:
- Remove completed applications from policy list
- Run setup with remaining applications only
-
Manual Policy Execution:
# Run individual failed policies /usr/local/bin/jamf policy -event install-failed-app
Network Recovery
For network-related failures:
-
Test Basic Connectivity:
ping -c 3 8.8.8.8 curl -I https://github.com
-
Reset Network Settings:
# Clear DNS cache dscacheutil -flushcache # Renew DHCP lease ipconfig set en0 DHCP
-
Retry Setup:
- Wait for stable connection
- Run setup during off-peak hours
- Consider wired connection
Debug and Development
Advanced development tools and techniques for customizing and extending Setup Your Mac.
Development Environment Setup
Testing Configuration
# Enable comprehensive debugging
debugMode="verbose"
debugModeSleepAmount="1" # Reduce sleep for faster testing
# Use test webhook
webhookURL="https://hooks.slack.com/services/TEST/WEBHOOK/URL"
# Test with minimal policies
testMode="true"
Mock Data for Development
# Use test data for development
if [ "${testMode}" == "true" ](/setup-your-mac/Setup-Your-Mac/wiki/-"${testMode}"-==-"true"-); then
buildingsListRaw="Test Building A,Test Building B"
departmentListRaw="Test Dept 1,Test Dept 2"
positionListRaw="Test Position 1,Test Position 2"
fi
Custom Function Development
Function Template
function customFunction() {
local parameter1="$1"
local parameter2="$2"
# Add function logic here
updateScriptLog "[CUSTOM] Function executed with: $parameter1, $parameter2"
# Return appropriate exit code
return 0
}
Error Handling Pattern
function robustFunction() {
local input="$1"
# Input validation
if [ -z "$input" ](/setup-your-mac/Setup-Your-Mac/wiki/--z-"$input"-); then
error "robustFunction: Missing required parameter"
return 1
fi
# Main function logic with error checking
if ! someOperation "$input"; then
error "robustFunction: Operation failed for $input"
return 1
fi
# Success logging
info "robustFunction: Successfully processed $input"
return 0
}
Custom Validation Scripts
Template for Custom Validation
#!/bin/bash
# Custom validation script template
function validate_custom_application() {
local app_name="$1"
local validation_criteria="$2"
# Check if application exists
if [ ! -d "/Applications/${app_name}.app" ](/setup-your-mac/Setup-Your-Mac/wiki/-!--d-"/Applications/${app_name}.app"-); then
echo "failed"
return 1
fi
# Check if application is running (if required)
if [ "$validation_criteria" == "running" ](/setup-your-mac/Setup-Your-Mac/wiki/-"$validation_criteria"-==-"running"-); then
if ! pgrep -f "$app_name" > /dev/null; then
echo "failed"
return 1
fi
fi
# Check configuration files (if required)
if [ "$validation_criteria" == "configured" ](/setup-your-mac/Setup-Your-Mac/wiki/-"$validation_criteria"-==-"configured"-); then
config_file="/Users/$USER/Library/Preferences/${app_name}.plist"
if [ ! -f "$config_file" ](/setup-your-mac/Setup-Your-Mac/wiki/-!--f-"$config_file"-); then
echo "failed"
return 1
fi
fi
echo "success"
return 0
}
# Main validation logic
app_name="$1"
criteria="$2"
result=$(validate_custom_application "$app_name" "$criteria")
echo "$result"
Extending Dialog Functionality
Custom Dialog Commands
function customDialogUpdate() {
local command="$1"
local value="$2"
case "$command" in
"custom-progress")
dialogUpdateSetupYourMac "progresstext: Custom operation: $value"
;;
"custom-listitem")
dialogUpdateSetupYourMac "listitem: $value: Custom Status"
;;
*)
error "Unknown custom dialog command: $command"
;;
esac
}
Advanced Progress Tracking
function advancedProgressUpdate() {
local current_step="$1"
local total_steps="$2"
local step_description="$3"
local progress_percentage=$(( (current_step * 100) / total_steps ))
dialogUpdateSetupYourMac "progress: $progress_percentage"
dialogUpdateSetupYourMac "progresstext: Step $current_step of $total_steps: $step_description"
# Custom logging for progress tracking
updateScriptLog "[PROGRESS] $current_step/$total_steps ($progress_percentage%): $step_description"
}
Integration with External Systems
Custom API Integration
function reportToExternalSystem() {
local status="$1"
local details="$2"
local api_endpoint="https://api.company.com/setup-status"
# Prepare JSON payload
local json_payload=$(cat <<EOF
{
"computer": "$(scutil --get ComputerName)",
"user": "$loggedInUser",
"status": "$status",
"details": "$details",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
)
# Send to external API
if curl -s -X POST "$api_endpoint" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
-d "$json_payload" > /dev/null; then
info "Successfully reported status to external system"
else
error "Failed to report status to external system"
fi
}
Database Integration
function logToDatabase() {
local event_type="$1"
local event_data="$2"
# Example SQL command (adjust for your database)
local sql_command="INSERT INTO setup_logs (computer_name, user_name, event_type, event_data, timestamp) VALUES ('$(scutil --get ComputerName)', '$loggedInUser', '$event_type', '$event_data', NOW())"
# Execute database command (example using mysql client)
if mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" -e "$sql_command" 2>/dev/null; then
info "Successfully logged event to database"
else
error "Failed to log event to database"
fi
}
Performance Optimization
Efficient Resource Monitoring
function monitorSystemResources() {
local cpu_threshold=80
local memory_threshold=90
# Check CPU usage
local cpu_usage=$(top -l 1 -n 0 | grep "CPU usage" | awk '{print $3}' | sed 's/%//')
if (( $(echo "$cpu_usage > $cpu_threshold" | bc -l) )); then
updateScriptLog "[PERFORMANCE] High CPU usage detected: ${cpu_usage}%"
sleep 2 # Brief pause to reduce load
fi
# Check memory pressure
local memory_pressure=$(memory_pressure | head -1 | awk '{print $5}')
if [ "$memory_pressure" == "critical" ](/setup-your-mac/Setup-Your-Mac/wiki/-"$memory_pressure"-==-"critical"-); then
updateScriptLog "[PERFORMANCE] Critical memory pressure detected"
# Trigger cleanup or pause operations
fi
}
Optimized Policy Execution
function optimizedPolicyExecution() {
local policies=("$@")
local max_concurrent=2
local running_count=0
for policy in "${policies[@]}"; do
# Monitor system resources before starting new policy
monitorSystemResources
# Limit concurrent executions
if (( running_count >= max_concurrent )); then
wait # Wait for background processes to complete
running_count=0
fi
# Execute policy in background if system resources allow
if (( cpu_usage < 70 )); then
run_jamf_trigger "$policy" &
((running_count++))
else
# Execute synchronously if system is busy
run_jamf_trigger "$policy"
fi
done
# Wait for all background processes to complete
wait
}
Testing and Quality Assurance
Automated Testing Framework
function runTestSuite() {
local test_results=()
# Test 1: Configuration validation
if validateConfiguration; then
test_results+=("PASS: Configuration validation")
else
test_results+=("FAIL: Configuration validation")
fi
# Test 2: Network connectivity
if testNetworkConnectivity; then
test_results+=("PASS: Network connectivity")
else
test_results+=("FAIL: Network connectivity")
fi
# Test 3: Required dependencies
if checkDependencies; then
test_results+=("PASS: Dependencies check")
else
test_results+=("FAIL: Dependencies check")
fi
# Report test results
updateScriptLog "[TEST RESULTS] Test suite completed:"
for result in "${test_results[@]}"; do
updateScriptLog "[TEST RESULTS] $result"
done
}
function validateConfiguration() {
# Test JSON syntax
echo "$policyJSON" | jq . >/dev/null 2>&1 || return 1
# Test required variables
[ -n "$supportTeamName" ](/setup-your-mac/Setup-Your-Mac/wiki/--n-"$supportTeamName"-) || return 1
[ -n "$supportTeamEmail" ](/setup-your-mac/Setup-Your-Mac/wiki/--n-"$supportTeamEmail"-) || return 1
return 0
}
function testNetworkConnectivity() {
# Test basic connectivity
curl -s --max-time 10 "https://github.com" >/dev/null || return 1
# Test Jamf Pro server
curl -s --max-time 10 "$jamfProURL" >/dev/null || return 1
return 0
}
function checkDependencies() {
# Check swiftDialog
[ -x "/usr/local/bin/dialog" ](/setup-your-mac/Setup-Your-Mac/wiki/--x-"/usr/local/bin/dialog"-) || return 1
# Check Jamf binary
[ -x "/usr/local/bin/jamf" ](/setup-your-mac/Setup-Your-Mac/wiki/--x-"/usr/local/bin/jamf"-) || return 1
# Check required commands
command -v jq >/dev/null || return 1
command -v curl >/dev/null || return 1
return 0
}
See Also
Configuration and Setup
- Configuration Guide - Complete setup guide from basic parameters to advanced integration
- Best Practices - Security, performance, and operational guidelines
Core Documentation
- Setup Your Mac Overview - Main documentation with comprehensive technical architecture and implementation details
- Policy Validation Methods - Local vs Remote validation strategies
- SYM-Helper Application - Visual configuration tool
Getting Started
- Before You Begin - Prerequisites and requirements
- Jamf Pro Policy Pre-work - Essential Jamf Pro setup steps
- Deployment Methods - Different deployment approaches