Tutorial

Novas atualizações e melhorias para a Macfleet.

Aviso importante

Os exemplos de código e scripts fornecidos nestes tutoriais são apenas para fins educacionais. A Macfleet não é responsável por quaisquer problemas, danos ou vulnerabilidades de segurança que possam surgir do uso, modificação ou implementação destes exemplos. Sempre revise e teste o código em um ambiente seguro antes de usá-lo em sistemas de produção.

Remote Ring and Device Location Management on macOS

Manage device location and audio alerts across your MacFleet devices with comprehensive remote ring functionality, location tracking, and enterprise device recovery solutions. This tutorial covers remote ring implementation, audio management, and fleet-wide device location services.

Understanding Remote Ring and Device Location

Remote ring functionality on macOS provides essential device location capabilities:

  • Audio Alerts - Playing sounds to help locate nearby devices
  • Device Location - Finding misplaced or lost devices in enterprise environments
  • Fleet Management - Centralized device tracking and recovery
  • Security Enhancement - Anti-theft and device recovery capabilities

Enterprise Use Cases

Remote ring and location services benefit enterprise environments:

  • Asset Recovery - Quickly locate misplaced devices in large offices
  • Security Response - Audio alerts for theft prevention and device recovery
  • Inventory Management - Track device locations during audits and transitions
  • Emergency Protocols - Locate devices during evacuations or emergencies
  • User Assistance - Help users find their devices without IT intervention

Basic Remote Ring Implementation

Simple Remote Ring Script

#!/bin/bash

# Basic remote ring implementation
basic_remote_ring() {
    local ring_count="${1:-5}"
    local sound_file="${2:-/System/Library/Sounds/Submarine.aiff}"
    
    echo "=== Basic Remote Ring ==="
    echo "Ring count: $ring_count"
    echo "Sound file: $sound_file"
    echo ""
    
    # Validate sound file exists
    if [[ ! -f "$sound_file" ]]; then
        echo "Error: Sound file not found: $sound_file"
        echo "Using default system sound..."
        sound_file="/System/Library/Sounds/Ping.aiff"
    fi
    
    # Execute remote ring
    local count=1
    while [[ $count -le $ring_count ]]; do
        echo "Playing ring $count of $ring_count"
        afplay "$sound_file"
        count=$(( count + 1 ))
        
        # Add small delay between rings for better audio separation
        sleep 1
    done
    
    echo "Remote ring completed: $ring_count rings played"
}

# Enhanced remote ring with validation
enhanced_remote_ring() {
    local ring_count="${1:-5}"
    local sound_file="${2:-/System/Library/Sounds/Submarine.aiff}"
    local volume_level="${3:-75}"
    
    echo "=== Enhanced Remote Ring ==="
    echo "Ring count: $ring_count"
    echo "Sound file: $sound_file"
    echo "Volume level: $volume_level%"
    echo ""
    
    # Set system volume
    osascript -e "set volume output volume $volume_level"
    
    # Validate parameters
    if [[ $ring_count -lt 1 || $ring_count -gt 50 ]]; then
        echo "Warning: Ring count should be between 1 and 50, using default of 5"
        ring_count=5
    fi
    
    # Play rings with enhanced feedback
    local count=1
    while [[ $count -le $ring_count ]]; do
        echo "Ring $count/$ring_count - $(date '+%H:%M:%S')"
        
        if afplay "$sound_file" 2>/dev/null; then
            echo "✓ Ring played successfully"
        else
            echo "✗ Failed to play ring"
        fi
        
        count=$(( count + 1 ))
        
        # Progressive delay (shorter for multiple rings)
        if [[ $ring_count -gt 1 ]]; then
            sleep 0.5
        fi
    done
    
    echo "Enhanced remote ring completed at $(date '+%H:%M:%S')"
}

# Usage examples
# basic_remote_ring 3
# enhanced_remote_ring 5 "/System/Library/Sounds/Glass.aiff" 80

Available System Sounds

#!/bin/bash

# List and test available system sounds
list_system_sounds() {
    echo "=== Available System Sounds ==="
    echo "Location: /System/Library/Sounds/"
    echo ""
    
    local sounds_dir="/System/Library/Sounds"
    
    if [[ -d "$sounds_dir" ]]; then
        echo "Available sound files:"
        ls -1 "$sounds_dir"/*.aiff 2>/dev/null | while read -r sound_file; do
            local sound_name=$(basename "$sound_file" .aiff)
            echo "  - $sound_name"
        done
    else
        echo "System sounds directory not found"
    fi
    
    echo ""
    echo "Popular choices for remote ring:"
    echo "  - Submarine.aiff (deep, attention-getting)"
    echo "  - Glass.aiff (clear, distinctive)"
    echo "  - Ping.aiff (sharp, noticeable)"
    echo "  - Sosumi.aiff (classic Mac sound)"
    echo "  - Purr.aiff (softer option)"
}

# Test specific sound file
test_sound_file() {
    local sound_file="$1"
    
    if [[ -z "$sound_file" ]]; then
        echo "Usage: test_sound_file <sound_file_path>"
        return 1
    fi
    
    echo "Testing sound file: $sound_file"
    
    if [[ -f "$sound_file" ]]; then
        echo "Playing test sound..."
        afplay "$sound_file"
        echo "✓ Sound test completed"
    else
        echo "✗ Sound file not found: $sound_file"
        return 1
    fi
}

# Usage
list_system_sounds

Volume and Audio Management

#!/bin/bash

# Manage system volume for remote ring
manage_system_volume() {
    local action="${1:-get}"
    local volume_level="${2:-50}"
    
    case "$action" in
        "get")
            echo "=== Current System Volume ==="
            local current_volume=$(osascript -e "output volume of (get volume settings)")
            echo "Current volume: $current_volume%"
            
            # Check if muted
            local mute_status=$(osascript -e "output muted of (get volume settings)")
            if [[ "$mute_status" == "true" ]]; then
                echo "Status: MUTED"
            else
                echo "Status: UNMUTED"
            fi
            ;;
        "set")
            echo "=== Setting System Volume ==="
            echo "Target volume: $volume_level%"
            
            # Unmute if muted
            osascript -e "set volume without output muted"
            
            # Set volume level
            osascript -e "set volume output volume $volume_level"
            
            echo "✓ Volume set to $volume_level%"
            ;;
        "mute")
            echo "=== Muting System ==="
            osascript -e "set volume with output muted"
            echo "✓ System muted"
            ;;
        "unmute")
            echo "=== Unmuting System ==="
            osascript -e "set volume without output muted"
            echo "✓ System unmuted"
            ;;
        "max")
            echo "=== Setting Maximum Volume ==="
            osascript -e "set volume without output muted"
            osascript -e "set volume output volume 100"
            echo "✓ Volume set to maximum (100%)"
            ;;
        *)
            echo "Usage: manage_system_volume [get|set|mute|unmute|max] [volume_level]"
            return 1
            ;;
    esac
}

# Emergency volume override for remote ring
emergency_volume_override() {
    echo "=== Emergency Volume Override ==="
    echo "Overriding all audio settings for maximum audibility"
    
    # Store current settings
    local current_volume=$(osascript -e "output volume of (get volume settings)")
    local current_mute=$(osascript -e "output muted of (get volume settings)")
    
    echo "Current settings saved - Volume: $current_volume%, Muted: $current_mute"
    
    # Set emergency volume
    osascript -e "set volume without output muted"
    osascript -e "set volume output volume 100"
    
    echo "✓ Emergency volume activated (100%, unmuted)"
    
    # Return function to restore settings
    echo "To restore previous settings, run:"
    echo "osascript -e \"set volume output volume $current_volume\""
    if [[ "$current_mute" == "true" ]]; then
        echo "osascript -e \"set volume with output muted\""
    fi
}

# Usage
manage_system_volume "get"

Advanced Remote Ring Features

Intelligent Remote Ring System

#!/bin/bash

# Intelligent remote ring with adaptive behavior
intelligent_remote_ring() {
    local ring_pattern="${1:-standard}"
    local duration="${2:-30}"
    local priority_level="${3:-normal}"
    
    echo "=== Intelligent Remote Ring System ==="
    echo "Pattern: $ring_pattern"
    echo "Duration: ${duration}s"
    echo "Priority: $priority_level"
    echo ""
    
    # Set volume based on priority
    case "$priority_level" in
        "low")
            local volume=40
            local sound="/System/Library/Sounds/Purr.aiff"
            ;;
        "normal")
            local volume=70
            local sound="/System/Library/Sounds/Submarine.aiff"
            ;;
        "high")
            local volume=85
            local sound="/System/Library/Sounds/Glass.aiff"
            ;;
        "emergency")
            local volume=100
            local sound="/System/Library/Sounds/Sosumi.aiff"
            emergency_volume_override
            ;;
        *)
            local volume=70
            local sound="/System/Library/Sounds/Submarine.aiff"
            ;;
    esac
    
    # Set system volume
    osascript -e "set volume output volume $volume"
    
    # Execute ring pattern
    case "$ring_pattern" in
        "standard")
            standard_ring_pattern "$duration" "$sound"
            ;;
        "pulse")
            pulse_ring_pattern "$duration" "$sound"
            ;;
        "escalating")
            escalating_ring_pattern "$duration" "$sound"
            ;;
        "morse_sos")
            morse_sos_pattern "$duration" "$sound"
            ;;
        "heartbeat")
            heartbeat_pattern "$duration" "$sound"
            ;;
        *)
            echo "Unknown pattern: $ring_pattern, using standard"
            standard_ring_pattern "$duration" "$sound"
            ;;
    esac
}

# Standard ring pattern
standard_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Playing standard ring pattern for ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        afplay "$sound"
        sleep 2
    done
}

# Pulse ring pattern (quick bursts)
pulse_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Playing pulse ring pattern for ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # Triple pulse
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.3
        done
        sleep 2
    done
}

# Escalating ring pattern (increasing frequency)
escalating_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    local sleep_interval=3
    
    echo "Playing escalating ring pattern for ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        afplay "$sound"
        sleep $sleep_interval
        
        # Decrease interval (increase frequency)
        if [[ $sleep_interval -gt 1 ]]; then
            sleep_interval=$((sleep_interval - 1))
        fi
    done
}

# Morse code SOS pattern
morse_sos_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Playing Morse SOS pattern for ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # S (3 short)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.2
            sleep 0.3
        done
        sleep 0.5
        
        # O (3 long)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.6
            sleep 0.3
        done
        sleep 0.5
        
        # S (3 short)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.2
            sleep 0.3
        done
        
        sleep 3
    done
}

# Heartbeat pattern
heartbeat_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Playing heartbeat pattern for ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # Double beat
        afplay "$sound" &
        sleep 0.2
        afplay "$sound" &
        sleep 1.5
    done
}

# Usage examples
# intelligent_remote_ring "pulse" 30 "high"
# intelligent_remote_ring "morse_sos" 60 "emergency"

Location-Based Ring Management

#!/bin/bash

# Location-aware remote ring
location_based_ring() {
    local location_context="${1:-office}"
    local time_context="${2:-business_hours}"
    
    echo "=== Location-Based Ring Management ==="
    echo "Location context: $location_context"
    echo "Time context: $time_context"
    echo ""
    
    # Determine appropriate ring settings based on context
    case "$location_context" in
        "office")
            handle_office_environment "$time_context"
            ;;
        "meeting_room")
            handle_meeting_room_environment "$time_context"
            ;;
        "public_space")
            handle_public_space_environment "$time_context"
            ;;
        "home_office")
            handle_home_office_environment "$time_context"
            ;;
        "warehouse")
            handle_warehouse_environment "$time_context"
            ;;
        *)
            echo "Unknown location context, using default settings"
            intelligent_remote_ring "standard" 30 "normal"
            ;;
    esac
}

# Office environment settings
handle_office_environment() {
    local time_context="$1"
    
    echo "Configuring for office environment..."
    
    case "$time_context" in
        "business_hours")
            # Moderate volume, professional sound
            intelligent_remote_ring "standard" 20 "normal"
            ;;
        "after_hours")
            # Higher volume, more attention-getting
            intelligent_remote_ring "escalating" 45 "high"
            ;;
        "lunch_break")
            # Softer approach during break times
            intelligent_remote_ring "pulse" 25 "low"
            ;;
    esac
}

# Meeting room environment settings
handle_meeting_room_environment() {
    local time_context="$1"
    
    echo "Configuring for meeting room environment..."
    
    # Always use discrete settings in meeting areas
    intelligent_remote_ring "heartbeat" 15 "low"
}

# Public space environment settings
handle_public_space_environment() {
    local time_context="$1"
    
    echo "Configuring for public space environment..."
    
    # Discrete but effective
    intelligent_remote_ring "pulse" 30 "normal"
}

# Home office environment settings
handle_home_office_environment() {
    local time_context="$1"
    
    echo "Configuring for home office environment..."
    
    case "$time_context" in
        "business_hours")
            # Can be more assertive at home
            intelligent_remote_ring "escalating" 40 "high"
            ;;
        "evening")
            # Considerate of household
            intelligent_remote_ring "standard" 20 "low"
            ;;
    esac
}

# Warehouse environment settings
handle_warehouse_environment() {
    local time_context="$1"
    
    echo "Configuring for warehouse environment..."
    
    # Loud environment requires maximum volume
    intelligent_remote_ring "morse_sos" 60 "emergency"
}

# Usage
# location_based_ring "office" "business_hours"

Enterprise Remote Ring Management System

#!/bin/bash

# MacFleet Remote Ring and Device Location Management Tool
# Comprehensive device location, audio alerts, and fleet tracking

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_remote_ring.log"
REPORT_DIR="/etc/macfleet/reports/location"
CONFIG_DIR="/etc/macfleet/location"
SOUND_DIR="/etc/macfleet/sounds"
POLICY_DIR="/etc/macfleet/policies/location"

# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$SOUND_DIR" "$POLICY_DIR"

# Ring policies for different scenarios
declare -A RING_POLICIES=(
    ["standard_office"]="volume:70,pattern:standard,duration:30,sound:submarine"
    ["quiet_environment"]="volume:40,pattern:pulse,duration:15,sound:purr"
    ["emergency_locate"]="volume:100,pattern:morse_sos,duration:120,sound:sosumi"
    ["meeting_room"]="volume:30,pattern:heartbeat,duration:10,sound:glass"
    ["warehouse_floor"]="volume:100,pattern:escalating,duration:60,sound:submarine"
    ["public_area"]="volume:60,pattern:pulse,duration:25,sound:ping"
    ["after_hours"]="volume:85,pattern:escalating,duration:45,sound:glass"
    ["healthcare_facility"]="volume:50,pattern:heartbeat,duration:20,sound:purr"
    ["education_campus"]="volume:65,pattern:standard,duration:30,sound:ping"
    ["retail_store"]="volume:75,pattern:pulse,duration:35,sound:submarine"
)

# Location tracking configurations
declare -A LOCATION_CONFIGS=(
    ["high_security"]="gps_tracking,wifi_triangulation,bluetooth_beacons,audit_logging"
    ["standard_office"]="wifi_tracking,bluetooth_detection,basic_logging"
    ["public_access"]="limited_tracking,privacy_compliant,minimal_logging"
    ["healthcare"]="hipaa_compliant,secure_tracking,encrypted_logs,audit_trail"
    ["education"]="ferpa_compliant,student_privacy,controlled_tracking,parent_notification"
    ["retail"]="customer_privacy,basic_tracking,loss_prevention,inventory_integration"
)

# Emergency response levels
declare -A EMERGENCY_LEVELS=(
    ["green"]="normal_operation,standard_ring,basic_logging"
    ["yellow"]="elevated_response,enhanced_ring,increased_logging"
    ["orange"]="urgent_response,emergency_ring,comprehensive_logging"
    ["red"]="critical_response,maximum_ring,full_audit_trail"
)

# Logging function
log_action() {
    local message="$1"
    local severity="${2:-INFO}"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$severity] $message" | tee -a "$LOG_FILE"
}

# Enterprise remote ring with full management
enterprise_remote_ring() {
    local device_id="${1:-$(hostname)}"
    local ring_policy="${2:-standard_office}"
    local location_context="${3:-office}"
    local emergency_level="${4:-green}"
    local initiated_by="${5:-$(whoami)}"
    
    log_action "Starting enterprise remote ring" "INFO"
    log_action "Device: $device_id, Policy: $ring_policy, Context: $location_context" "INFO"
    
    echo "=== Enterprise Remote Ring Management ==="
    echo "Device ID: $device_id"
    echo "Ring Policy: $ring_policy"
    echo "Location Context: $location_context"
    echo "Emergency Level: $emergency_level"
    echo "Initiated By: $initiated_by"
    echo "Ring ID: $(uuidgen)"
    echo ""
    
    # Parse ring policy
    local policy_settings="${RING_POLICIES[$ring_policy]}"
    if [[ -z "$policy_settings" ]]; then
        log_action "Unknown ring policy: $ring_policy, using standard_office" "WARNING"
        policy_settings="${RING_POLICIES[standard_office]}"
    fi
    
    # Extract policy parameters
    local volume=$(echo "$policy_settings" | grep -o 'volume:[0-9]*' | cut -d: -f2)
    local pattern=$(echo "$policy_settings" | grep -o 'pattern:[^,]*' | cut -d: -f2)
    local duration=$(echo "$policy_settings" | grep -o 'duration:[0-9]*' | cut -d: -f2)
    local sound=$(echo "$policy_settings" | grep -o 'sound:[^,]*' | cut -d: -f2)
    
    echo "--- Policy Configuration ---"
    echo "Volume: $volume%"
    echo "Pattern: $pattern"
    echo "Duration: ${duration}s"
    echo "Sound: $sound"
    
    # Apply emergency level modifications
    apply_emergency_modifications "$emergency_level" volume pattern duration
    
    # Execute pre-ring checks
    if ! pre_ring_validation "$device_id" "$location_context"; then
        log_action "Pre-ring validation failed" "ERROR"
        return 1
    fi
    
    # Record ring initiation
    record_ring_event "$device_id" "$ring_policy" "$location_context" "$initiated_by" "started"
    
    # Execute ring based on policy
    execute_policy_ring "$volume" "$pattern" "$duration" "$sound"
    
    # Record ring completion
    record_ring_event "$device_id" "$ring_policy" "$location_context" "$initiated_by" "completed"
    
    # Generate location report
    generate_location_report "$device_id" "$ring_policy" "$location_context"
    
    log_action "remote ring completed for device: $device_id" "INFO"
}

# Apply emergency level modifications
apply_emergency_modifications() {
    local emergency_level="$1"
    local -n vol_ref=$2
    local -n pat_ref=$3
    local -n dur_ref=$4
    
    echo "--- Emergency Level: $emergency_level ---"
    
    case "$emergency_level" in
        "yellow")
            vol_ref=$((vol_ref + 15))
            dur_ref=$((dur_ref + 10))
            echo "Enhanced response: Volume +15%, Duration +10s"
            ;;
        "orange")
            vol_ref=$((vol_ref + 25))
            dur_ref=$((dur_ref + 20))
            pat_ref="escalating"
            echo "Urgent response: Volume +25%, Duration +20s, Escalating pattern"
            ;;
        "red")
            vol_ref=100
            dur_ref=$((dur_ref * 2))
            pat_ref="morse_sos"
            echo "Critical response: Maximum volume, Double duration, SOS pattern"
            ;;
    esac
    
    # Cap volume at 100%
    if [[ $vol_ref -gt 100 ]]; then
        vol_ref=100
    fi
}

# Pre-ring validation
pre_ring_validation() {
    local device_id="$1"
    local location_context="$2"
    
    echo "--- Pre-Ring Validation ---"
    
    # Check audio system availability
    if ! command -v afplay >/dev/null 2>&1; then
        echo "✗ Audio system not available"
        log_action "Audio system check failed" "ERROR"
        return 1
    fi
    
    # Check if device is in do-not-disturb mode
    local dnd_status=$(defaults read ~/Library/Preferences/ByHost/com.apple.notificationcenterui.* doNotDisturb 2>/dev/null || echo "0")
    if [[ "$dnd_status" == "1" ]]; then
        echo "⚠️ Device is in Do Not Disturb mode"
        log_action "Device in DND mode - ring may be muted" "WARNING"
    fi
    
    # Check system volume
    local current_volume=$(osascript -e "output volume of (get volume settings)" 2>/dev/null || echo "50")
    echo "Current system volume: $current_volume%"
    
    # Check if muted
    local mute_status=$(osascript -e "output muted of (get volume settings)" 2>/dev/null || echo "false")
    if [[ "$mute_status" == "true" ]]; then
        echo "⚠️ System is currently muted"
        log_action "System muted - will override for ring" "WARNING"
    fi
    
    # Location-specific validations
    case "$location_context" in
        "meeting_room")
            echo "Meeting room context - using discrete settings"
            ;;
        "healthcare_facility")
            echo "Healthcare context - ensuring HIPAA compliance"
            ;;
        "education_campus")
            echo "Education context - ensuring appropriate volume levels"
            ;;
    esac
    
    echo "✓ Pre-ring validation completed"
    return 0
}

# Execute ring based on policy
execute_policy_ring() {
    local volume="$1"
    local pattern="$2"
    local duration="$3"
    local sound="$4"
    
    echo "--- Executing Ring ---"
    
    # Map sound name to file path
    local sound_file="/System/Library/Sounds/Submarine.aiff"  # Default
    case "$sound" in
        "submarine") sound_file="/System/Library/Sounds/Submarine.aiff" ;;
        "glass") sound_file="/System/Library/Sounds/Glass.aiff" ;;
        "ping") sound_file="/System/Library/Sounds/Ping.aiff" ;;
        "sosumi") sound_file="/System/Library/Sounds/Sosumi.aiff" ;;
        "purr") sound_file="/System/Library/Sounds/Purr.aiff" ;;
    esac
    
    # Store current audio settings
    local original_volume=$(osascript -e "output volume of (get volume settings)" 2>/dev/null || echo "50")
    local original_mute=$(osascript -e "output muted of (get volume settings)" 2>/dev/null || echo "false")
    
    # Set ring volume and unmute
    osascript -e "set volume without output muted" 2>/dev/null
    osascript -e "set volume output volume $volume" 2>/dev/null
    
    echo "Ring settings: Volume $volume%, Pattern $pattern, Duration ${duration}s"
    echo "Start time: $(date '+%H:%M:%S')"
    
    # Execute ring pattern
    case "$pattern" in
        "standard")
            standard_ring_pattern "$duration" "$sound_file"
            ;;
        "pulse")
            pulse_ring_pattern "$duration" "$sound_file"
            ;;
        "escalating")
            escalating_ring_pattern "$duration" "$sound_file"
            ;;
        "morse_sos")
            morse_sos_pattern "$duration" "$sound_file"
            ;;
        "heartbeat")
            heartbeat_pattern "$duration" "$sound_file"
            ;;
    esac
    
    echo "End time: $(date '+%H:%M:%S')"
    
    # Restore original audio settings
    osascript -e "set volume output volume $original_volume" 2>/dev/null
    if [[ "$original_mute" == "true" ]]; then
        osascript -e "set volume with output muted" 2>/dev/null
    fi
    
    echo "✓ Original audio settings restored"
}

# Record ring events for audit trail
record_ring_event() {
    local device_id="$1"
    local ring_policy="$2"
    local location_context="$3"
    local initiated_by="$4"
    local event_type="$5"
    
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    local event_file="$CONFIG_DIR/ring_events.log"
    
    echo "$timestamp,$device_id,$ring_policy,$location_context,$initiated_by,$event_type" >> "$event_file"
    
    log_action "Ring event recorded: $event_type for device $device_id" "INFO"
}

# Generate comprehensive location report
generate_location_report() {
    local device_id="$1"
    local ring_policy="$2"
    local location_context="$3"
    
    local report_file="$REPORT_DIR/location_report_${device_id}_$(date +%Y%m%d_%H%M%S).json"
    
    # Get system location information (if available)
    local wifi_network=$(networksetup -getairportnetwork en0 2>/dev/null | cut -d: -f2 | sed 's/^ *//' || echo "Unknown")
    local ip_address=$(ifconfig en0 | grep "inet " | awk '{print $2}' || echo "Unknown")
    
    cat > "$report_file" << EOF
{
    "location_report": {
        "report_metadata": {
            "report_id": "$(uuidgen)",
            "generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "device_id": "$device_id",
            "hostname": "$(hostname)",
            "script_version": "$SCRIPT_VERSION"
        },
        "ring_details": {
            "ring_policy": "$ring_policy",
            "location_context": "$location_context",
            "execution_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
        },
        "location_information": {
            "wifi_network": "$wifi_network",
            "ip_address": "$ip_address",
            "system_timezone": "$(date +%Z)",
            "estimated_location": "$location_context"
        },
        "system_information": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "audio_devices": "$(system_profiler SPAudioDataType | grep -A1 'Audio Devices:' | tail -1 | sed 's/^[ ]*//')"
        }
    }
}
EOF
    
    echo "Location report generated: $report_file"
    log_action "Location report generated: $report_file" "INFO"
}

# Fleet ring management
fleet_ring_management() {
    local operation="$1"
    local device_list="$2"
    local ring_policy="${3:-standard_office}"
    local emergency_level="${4:-green}"
    
    echo "=== Fleet Ring Management ==="
    echo "Operation: $operation"
    echo "Ring Policy: $ring_policy"
    echo "Emergency Level: $emergency_level"
    echo ""
    
    case "$operation" in
        "mass_ring")
            echo "Executing mass ring operation..."
            IFS=',' read -ra DEVICES <<< "$device_list"
            for device in "${DEVICES[@]}"; do
                echo "Ringing device: $device"
                enterprise_remote_ring "$device" "$ring_policy" "office" "$emergency_level"
                sleep 2  # Delay between devices
            done
            ;;
        "emergency_locate")
            echo "Emergency location protocol activated..."
            enterprise_remote_ring "$(hostname)" "emergency_locate" "unknown" "red"
            ;;
        "zone_ring")
            echo "Zone-based ring operation..."
            # Implementation for zone-based ringing
            ;;
        *)
            echo "Unknown operation: $operation"
            return 1
            ;;
    esac
}

# Main execution function
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    local param5="${6:-}"
    
    log_action "=== MacFleet Remote Ring Management Started ===" "INFO"
    log_action "Action: $action" "INFO"
    
    case "$action" in
        "ring")
            if [[ -z "$param1" ]]; then
                param1="$(hostname)"
            fi
            enterprise_remote_ring "$param1" "$param2" "$param3" "$param4" "$param5"
            ;;
        "emergency")
            echo "Emergency ring activated for current device"
            enterprise_remote_ring "$(hostname)" "emergency_locate" "unknown" "red" "$(whoami)"
            ;;
        "test")
            echo "Testing audio system..."
            test_sound_file "/System/Library/Sounds/Ping.aiff"
            ;;
        "volume")
            if [[ -z "$param1" ]]; then
                manage_system_volume "get"
            else
                manage_system_volume "$param1" "$param2"
            fi
            ;;
        "sounds")
            list_system_sounds
            ;;
        "fleet")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 fleet <operation> [device_list] [policy] [emergency_level]"
                echo "Operations: mass_ring, emergency_locate, zone_ring"
                exit 1
            fi
            fleet_ring_management "$param1" "$param2" "$param3" "$param4"
            ;;
        "help")
            echo "Usage: $0 [action] [options...]"
            echo "Actions:"
            echo "  ring [device_id] [policy] [location] [emergency_level] [initiated_by] - Execute remote ring"
            echo "  emergency - Emergency ring for current device"
            echo "  test - Test audio system"
            echo "  volume [action] [level] - Manage system volume"
            echo "  sounds - List available system sounds"
            echo "  fleet <operation> [device_list] [policy] [emergency_level] - Fleet operations"
            echo "  help - Show this help"
            echo ""
            echo "Ring Policies: ${!RING_POLICIES[*]}"
            echo "Emergency Levels: ${!EMERGENCY_LEVELS[*]}"
            ;;
        *)
            log_action "ERROR: Unknown action: $action" "ERROR"
            echo "Use '$0 help' for usage information"
            exit 1
            ;;
    esac
    
    log_action "=== Remote ring management completed ===" "INFO"
}

# Execute main function
main "$@"

Important Considerations

Audio System Requirements

  • afplay Command - macOS built-in audio player for sound file playback
  • System Sounds - Located in /System/Library/Sounds/ directory
  • Volume Control - Uses AppleScript for system volume management
  • Audio Permissions - Some features may require audio input/output permissions

Enterprise Deployment Notes

  • Network Latency - Remote ring commands may have network delays
  • Device States - Devices may be sleeping, muted, or in do-not-disturb mode
  • Privacy Compliance - Location tracking must comply with privacy regulations
  • Emergency Protocols - Emergency rings should override normal volume restrictions
  • Fleet Coordination - Mass ring operations should be staggered to avoid conflicts

Security Considerations

  • Access Control - Ring functionality should be restricted to authorized administrators
  • Audit Logging - All ring operations should be logged for security and compliance
  • Location Privacy - Device location information must be handled according to privacy policies
  • Emergency Override - Emergency situations may require bypassing normal restrictions

Tutorial

Novas atualizações e melhorias para a Macfleet.

Configurando um Runner do GitHub Actions em um Mac Mini (Apple Silicon)

Runner do GitHub Actions

GitHub Actions é uma plataforma poderosa de CI/CD que permite automatizar seus fluxos de trabalho de desenvolvimento de software. Embora o GitHub ofereça runners hospedados, runners auto-hospedados fornecem maior controle e personalização para sua configuração de CI/CD. Este tutorial o guia através da configuração e conexão de um runner auto-hospedado em um Mac mini para executar pipelines do macOS.

Pré-requisitos

Antes de começar, certifique-se de ter:

  • Um Mac mini (registre-se no Macfleet)
  • Um repositório GitHub com direitos de administrador
  • Um gerenciador de pacotes instalado (preferencialmente Homebrew)
  • Git instalado em seu sistema

Passo 1: Criar uma Conta de Usuário Dedicada

Primeiro, crie uma conta de usuário dedicada para o runner do GitHub Actions:

# Criar a conta de usuário 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Definir a senha para o usuário
sudo dscl . -passwd /Users/gh-runner sua_senha

# Adicionar 'gh-runner' ao grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Mude para a nova conta de usuário:

su gh-runner

Passo 2: Instalar Software Necessário

Instale Git e Rosetta 2 (se estiver usando Apple Silicon):

# Instalar Git se ainda não estiver instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Passo 3: Configurar o Runner do GitHub Actions

  1. Vá para seu repositório GitHub
  2. Navegue para Configurações > Actions > Runners

Runner do GitHub Actions

  1. Clique em "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecione macOS como imagem do runner e ARM64 como arquitetura
  3. Siga os comandos fornecidos para baixar e configurar o runner

Runner do GitHub Actions

Crie um arquivo .env no diretório _work do runner:

# arquivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Execute o script run.sh em seu diretório do runner para completar a configuração.
  2. Verifique se o runner está ativo e ouvindo por trabalhos no terminal e verifique as configurações do repositório GitHub para a associação do runner e status Idle.

Runner do GitHub Actions

Passo 4: Configurar Sudoers (Opcional)

Se suas ações requerem privilégios de root, configure o arquivo sudoers:

sudo visudo

Adicione a seguinte linha:

gh-runner ALL=(ALL) NOPASSWD: ALL

Passo 5: Usar o Runner em Fluxos de Trabalho

Configure seu fluxo de trabalho do GitHub Actions para usar o runner auto-hospedado:

name: Fluxo de trabalho de exemplo

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

O runner está autenticado em seu repositório e rotulado com self-hosted, macOS, e ARM64. Use-o em seus fluxos de trabalho especificando estes rótulos no campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Melhores Práticas

  • Mantenha seu software do runner atualizado
  • Monitore regularmente os logs do runner para problemas
  • Use rótulos específicos para diferentes tipos de runners
  • Implemente medidas de segurança adequadas
  • Considere usar múltiplos runners para balanceamento de carga

Solução de Problemas

Problemas comuns e soluções:

  1. Runner não conectando:

    • Verifique conectividade de rede
    • Verifique validade do token GitHub
    • Certifique-se de permissões adequadas
  2. Falhas de build:

    • Verifique instalação do Xcode
    • Verifique dependências necessárias
    • Revise logs do fluxo de trabalho
  3. Problemas de permissão:

    • Verifique permissões do usuário
    • Verifique configuração sudoers
    • Revise permissões do sistema de arquivos

Conclusão

Agora você tem um runner auto-hospedado do GitHub Actions configurado em seu Mac mini. Esta configuração fornece mais controle sobre seu ambiente CI/CD e permite executar fluxos de trabalho específicos do macOS de forma eficiente.

Lembre-se de manter regularmente seu runner e mantê-lo atualizado com os patches de segurança e versões de software mais recentes.

Aplicativo Nativo

Aplicativo nativo do Macfleet

Guia de Instalação do Macfleet

Macfleet é uma solução poderosa de gerenciamento de frota projetada especificamente para ambientes Mac Mini hospedados na nuvem. Como provedor de hospedagem na nuvem Mac Mini, você pode usar o Macfleet para monitorar, gerenciar e otimizar toda sua frota de instâncias Mac virtualizadas.

Este guia de instalação o conduzirá através da configuração do monitoramento do Macfleet em sistemas macOS, Windows e Linux para garantir supervisão abrangente de sua infraestrutura na nuvem.

🍎 macOS

  • Baixe o arquivo .dmg para Mac aqui
  • Clique duas vezes no arquivo .dmg baixado
  • Arraste o aplicativo Macfleet para a pasta Aplicativos
  • Ejete o arquivo .dmg
  • Abra Preferências do Sistema > Segurança e Privacidade
    • Aba Privacidade > Acessibilidade
    • Marque Macfleet para permitir monitoramento
  • Inicie o Macfleet a partir de Aplicativos
  • O rastreamento inicia automaticamente

🪟 Windows

  • Baixe o arquivo .exe para Windows aqui
  • Clique com o botão direito no arquivo .exe > "Executar como administrador"
  • Siga o assistente de instalação
  • Aceite os termos e condições
  • Permita no Windows Defender se solicitado
  • Conceda permissões de monitoramento de aplicativo
  • Inicie o Macfleet a partir do Menu Iniciar
  • O aplicativo começa o rastreamento automaticamente

🐧 Linux

  • Baixe o pacote .deb (Ubuntu/Debian) ou .rpm (CentOS/RHEL) aqui
  • Instale usando seu gerenciador de pacotes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permita permissões de acesso X11 se solicitado
  • Adicione o usuário aos grupos apropriados se necessário
  • Inicie o Macfleet a partir do menu Aplicativos
  • O aplicativo começa o rastreamento automaticamente

Nota: Após a instalação em todos os sistemas, faça login com suas credenciais do Macfleet para sincronizar dados com seu painel de controle.