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:

  1. Script Architecture - High-level technical overview
  2. Function Reference - All 40+ functions with line numbers and usage
  3. Troubleshooting Guide - Common issues and debug procedures
  4. 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

  1. Pre-flight Checks - System validation, user session, dependencies
  2. Configuration Loading - Parameter processing, JSON parsing
  3. Welcome Dialog - User input collection, network testing
  4. Policy Execution - Sequential policy processing with validation
  5. Progress Tracking - Real-time dialog updates, error handling
  6. 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 indentation
  • welcomeDialog() (Line 204) - Welcome dialog operations
  • updateSetupYourMacDialog() (Line 221) - Main dialog operations
  • updateFailureDialog() (Line 225) - Failure dialog operations
  • updateSuccessDialog() (Line 229) - Success messages
  • finaliseUserExperience() (Line 233) - User experience finalization
  • completionActionOut() (Line 237) - Completion actions
  • quitOut() (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 action
  • sleep - Wait specified time
  • Shut 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:

  1. Automatic Installation:

    # Script will attempt automatic download
    # Check script log for download progress
    tail -f /var/log/setup-your-mac.log
    
  2. 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 /
    
  3. 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:

  1. Check Jamf Binary:

    /usr/local/bin/jamf checkJSSConnection
    /usr/local/bin/jamf policy -event install-office -verbose
    
  2. Verify Policy Configuration:

    • Policy has Custom Trigger
    • Policy is enabled
    • Scope includes target computers
    • Frequency set to "Ongoing"
  3. Check Network Connectivity:

    curl -I https://your-jamf-server.com
    ping your-jamf-server.com
    
  4. 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:

  1. Check networkQuality Availability:

    # macOS 12+ required
    which networkQuality
    networkQuality -v
    
  2. Disable Network Testing:

    # In script configuration
    configurationDownloadEstimation="false"
    
  3. 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

  1. 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
    
  2. Time-based Analysis:

    grep "$(date '+%Y-%m-%d')" /var/log/setup-your-mac.log
    
  3. 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:

  1. Check User Session:

    # Verify user is logged in
    stat -f%Su /dev/console
    
    # Check for console user
    ls -la /dev/console
    
  2. Verify Dialog Process:

    ps aux | grep dialog
    
  3. 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:

  1. Kill Existing Dialogs:

    killall Dialog 2>/dev/null
    
  2. Check Command File:

    # Verify command file exists and is writable
    ls -la /var/tmp/dialog.log
    
  3. 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:

  1. Verify Policy Count:

    # Check that policy array matches actual policies
    echo "${policyJSON}" | jq '. | length'
    
  2. Reset Progress:

    dialogUpdateSetupYourMac "progress: reset"
    

Welcome Dialog User Input Issues

Symptoms:

  • Fields not pre-populating
  • Validation errors
  • Dropdown menus empty

Solutions:

  1. Check Field Configuration:

    # Verify prompt variables are set correctly
    echo "Username prompt: ${promptForUsername}"
    echo "Buildings list: ${buildingsList}"
    
  2. Validate JSON Syntax:

    # Test JSON generation
    echo "${welcomeJSON}" | jq .
    
  3. Review Field Dependencies:

    • Email requires emailEnding variable
    • Dropdowns require populated list variables
    • Pre-fill options require current user data

Network and Connectivity Issues

Download Failures

Symptoms:

  • Policies fail during download phase
  • Large applications not installing
  • Intermittent connection issues

Troubleshooting:

  1. Check Available Bandwidth:

    networkQuality -s
    
  2. Test Direct Downloads:

    curl -I "https://your-distribution-point.com/package.pkg"
    
  3. 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:

  1. Test Webhook URL:

    curl -X POST "${webhookURL}" \
         -H "Content-Type: application/json" \
         -d '{"text": "Test message"}'
    
  2. Verify URL Format:

    • Teams: https://outlook.office.com/webhook/...
    • Slack: https://hooks.slack.com/services/...
  3. 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:

  1. Configure Proxy Settings:

    # Check system proxy settings
    networksetup -getwebproxy "Wi-Fi"
    networksetup -getsecurewebproxy "Wi-Fi"
    
  2. Test Connectivity:

    curl -v "https://github.com/swiftDialog/swiftDialog/releases"
    curl -v "https://your-jamf-server.com"
    
  3. 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:

  1. File Path Validation:

    # Common incorrect paths
    /Applications/App Name.app              # Correct
    /Applications/App Name.app/             # Incorrect (trailing slash)
    /Applications/App Name                  # Incorrect (missing .app)
    
  2. Process Validation:

    # Check if process is running
    pgrep -f "Application Name"
    
  3. 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:

  1. Verify Configuration Names:

    echo "Config 1: ${configurationOneName}"
    echo "Config 2: ${configurationTwoName}"
    echo "Config 3: ${configurationThreeName}"
    
  2. Check Policy JSON:

    # Validate JSON syntax
    echo "${policyJSONConfiguration1}" | jq .
    
  3. 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:

  1. Check Recon Execution:

    /usr/local/bin/jamf recon -verbose
    
  2. Verify Computer Name Settings:

    # Check current computer name
    scutil --get ComputerName
    scutil --get LocalHostName
    
  3. 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:

  1. Monitor Resource Usage:

    top -o cpu | grep -E "(jamf|dialog|installer)"
    
  2. Stagger Policy Execution:

    • Add delays between policies
    • Reduce concurrent operations
    • Optimize policy order
  3. Check Available Resources:

    # Memory usage
    vm_stat
    
    # Disk space
    df -h
    

Disk Space Issues

Symptoms:

  • Installation failures
  • Download errors
  • System warnings

Solutions:

  1. Check Available Space:

    df -h /
    # Minimum 10GB recommended for setup
    
  2. 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*
    
  3. Monitor Disk Usage:

    du -sh /Applications/*
    

Memory Issues

Symptoms:

  • System slowdown
  • Application crashes
  • Dialog freezing

Solutions:

  1. Check Memory Pressure:

    memory_pressure
    
  2. 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:

  1. Check OS Requirements:

    sw_vers -productVersion
    # Minimum: macOS 12.0 for swiftDialog
    
  2. 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:

  1. Check Setup Assistant Status:

    ps aux | grep "Setup Assistant"
    
  2. 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:

  1. Check Power Status:

    pmset -g batt
    
  2. 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:

  1. Verify Script Execution:

    # Must run as root
    whoami
    # Should return: root
    
  2. 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:

  1. Kill All Processes:

    killall Dialog 2>/dev/null
    killall caffeinate 2>/dev/null
    pkill -f "Setup Your Mac"
    
  2. Remove Temporary Files:

    rm -f /var/tmp/dialog.log
    rm -f /var/tmp/welcome.log
    rm -f /var/tmp/failure.log
    
  3. 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:

  1. Identify Completed Policies:

    # Check application installations
    ls /Applications/ | grep -E "(Office|Chrome|Adobe)"
    
  2. Create Minimal Configuration:

    • Remove completed applications from policy list
    • Run setup with remaining applications only
  3. Manual Policy Execution:

    # Run individual failed policies
    /usr/local/bin/jamf policy -event install-failed-app
    

Network Recovery

For network-related failures:

  1. Test Basic Connectivity:

    ping -c 3 8.8.8.8
    curl -I https://github.com
    
  2. Reset Network Settings:

    # Clear DNS cache
    dscacheutil -flushcache
    
    # Renew DHCP lease
    ipconfig set en0 DHCP
    
  3. 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

Core Documentation

Getting Started