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.

Bluetooth Management on macOS

Control and manage Bluetooth settings across your MacFleet devices using advanced command-line tools. This tutorial covers Bluetooth status monitoring, power state management, and enterprise-grade fleet control with comprehensive logging and security features.

Understanding macOS Bluetooth Management

macOS provides comprehensive Bluetooth control through several mechanisms:

  • defaults - Direct manipulation of Bluetooth preferences via plist files
  • bluetoothd - The core Bluetooth daemon that handles all Bluetooth operations
  • launchctl - Service management for starting/stopping Bluetooth services
  • blued - Legacy Bluetooth daemon name used in older macOS versions

The primary configuration file is located at /Library/Preferences/com.apple.Bluetooth with the ControllerPowerState key controlling the power state.

Basic Bluetooth Status Management

Check Bluetooth Status

#!/bin/bash

# Check current Bluetooth power state
check_bluetooth_status() {
    local status
    status=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    if [[ "$status" == "1" ]]; then
        echo "Bluetooth is ON"
        return 0
    elif [[ "$status" == "0" ]]; then
        echo "Bluetooth is OFF"
        return 1
    else
        echo "Bluetooth status unknown or not configured"
        return 2
    fi
}

# Execute status check
check_bluetooth_status

Turn Bluetooth ON

#!/bin/bash

# Turn Bluetooth ON using defaults and daemon restart
turn_bluetooth_on() {
    echo "Turning Bluetooth ON..."
    
    # Set Bluetooth power state to ON
    sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 1
    
    # Restart Bluetooth daemon (try both modern and legacy daemon names)
    if pgrep bluetoothd >/dev/null 2>&1; then
        sudo killall -HUP bluetoothd
        echo "Bluetooth daemon (bluetoothd) restarted"
    elif pgrep blued >/dev/null 2>&1; then
        sudo killall -HUP blued
        echo "Bluetooth daemon (blued) restarted"
    else
        echo "Warning: Bluetooth daemon not found"
    fi
    
    # Wait for changes to take effect
    sleep 3
    
    # Verify the change
    if check_bluetooth_status >/dev/null; then
        echo "✅ Bluetooth successfully turned ON"
        return 0
    else
        echo "❌ Failed to turn Bluetooth ON"
        return 1
    fi
}

# Helper function for status checking
check_bluetooth_status() {
    local status
    status=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    [[ "$status" == "1" ]]
}

# Execute
turn_bluetooth_on

Turn Bluetooth OFF

#!/bin/bash

# Turn Bluetooth OFF using defaults and daemon restart
turn_bluetooth_off() {
    echo "Turning Bluetooth OFF..."
    
    # Set Bluetooth power state to OFF
    sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 0
    
    # Restart Bluetooth daemon
    if pgrep bluetoothd >/dev/null 2>&1; then
        sudo killall -HUP bluetoothd
        echo "Bluetooth daemon (bluetoothd) restarted"
    elif pgrep blued >/dev/null 2>&1; then
        sudo killall -HUP blued
        echo "Bluetooth daemon (blued) restarted"
    else
        echo "Warning: Bluetooth daemon not found"
    fi
    
    # Wait for changes to take effect
    sleep 3
    
    # Verify the change
    if ! check_bluetooth_status >/dev/null; then
        echo "✅ Bluetooth successfully turned OFF"
        return 0
    else
        echo "❌ Failed to turn Bluetooth OFF"
        return 1
    fi
}

# Helper function for status checking
check_bluetooth_status() {
    local status
    status=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    [[ "$status" == "1" ]]
}

# Execute
turn_bluetooth_off

Advanced Bluetooth Management with launchctl

Using launchctl for Service Management

#!/bin/bash

# Advanced Bluetooth control using launchctl service management
bluetooth_service_control() {
    local action="$1"  # on, off, restart, status
    local daemon_name
    
    # Determine the correct daemon name based on macOS version
    if launchctl list | grep -q "com.apple.bluetoothd"; then
        daemon_name="com.apple.bluetoothd"
    elif launchctl list | grep -q "com.apple.blued"; then
        daemon_name="com.apple.blued"
    else
        echo "❌ Bluetooth daemon not found in launchctl"
        return 1
    fi
    
    case "$action" in
        "on")
            echo "Enabling Bluetooth..."
            sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 1
            sudo launchctl stop "$daemon_name"
            sleep 2
            sudo launchctl start "$daemon_name"
            sleep 3
            echo "✅ Bluetooth enabled using launchctl"
            ;;
        "off")
            echo "Disabling Bluetooth..."
            sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 0
            sudo launchctl stop "$daemon_name"
            sleep 2
            sudo launchctl start "$daemon_name"
            sleep 3
            echo "✅ Bluetooth disabled using launchctl"
            ;;
        "restart")
            echo "Restarting Bluetooth service..."
            sudo launchctl stop "$daemon_name"
            sleep 2
            sudo launchctl start "$daemon_name"
            sleep 3
            echo "✅ Bluetooth service restarted"
            ;;
        "status")
            echo "Bluetooth daemon status: $daemon_name"
            if launchctl list | grep -q "$daemon_name"; then
                echo "✅ Bluetooth service is running"
                
                # Check power state
                local power_state
                power_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
                echo "Power state: $([[ "$power_state" == "1" ]] && echo "ON" || echo "OFF")"
            else
                echo "❌ Bluetooth service is not running"
            fi
            ;;
        *)
            echo "Usage: bluetooth_service_control {on|off|restart|status}"
            return 1
            ;;
    esac
}

# Examples
bluetooth_service_control "status"
# bluetooth_service_control "on"
# bluetooth_service_control "off"
# bluetooth_service_control "restart"

Enterprise Bluetooth Management System

#!/bin/bash

# MacFleet Enterprise Bluetooth Management System
# Comprehensive Bluetooth control with logging, monitoring, and fleet management

# Configuration
LOG_FILE="/var/log/macfleet_bluetooth.log"
CONFIG_FILE="/etc/macfleet/bluetooth_config.conf"
BACKUP_DIR="/var/backups/macfleet/bluetooth"
API_ENDPOINT="https://api.macfleet.com/v1/bluetooth"

# Create directory structure
setup_directories() {
    mkdir -p "$(dirname "$LOG_FILE")" "$BACKUP_DIR" "$(dirname "$CONFIG_FILE")"
    touch "$LOG_FILE"
}

# Logging function
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Get detailed Bluetooth information
get_bluetooth_info() {
    local info_json="{"
    
    # Power state
    local power_state
    power_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null || echo "unknown")
    info_json+="\"power_state\": \"$power_state\","
    
    # Daemon status
    local daemon_running=false
    if pgrep bluetoothd >/dev/null 2>&1 || pgrep blued >/dev/null 2>&1; then
        daemon_running=true
    fi
    info_json+="\"daemon_running\": $daemon_running,"
    
    # macOS version
    local macos_version
    macos_version=$(sw_vers -productVersion)
    info_json+="\"macos_version\": \"$macos_version\","
    
    # System hardware
    local hardware_model
    hardware_model=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}' | xargs)
    info_json+="\"hardware_model\": \"$hardware_model\","
    
    # Bluetooth controller info
    local bt_controller=""
    if system_profiler SPBluetoothDataType >/dev/null 2>&1; then
        bt_controller=$(system_profiler SPBluetoothDataType | grep -A5 "Apple Bluetooth Software" | grep "Version" | awk -F': ' '{print $2}' | xargs)
    fi
    info_json+="\"bluetooth_version\": \"$bt_controller\","
    
    # Timestamp
    info_json+="\"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\""
    info_json+="}"
    
    echo "$info_json"
}

# Backup current Bluetooth configuration
backup_bluetooth_config() {
    local backup_file="$BACKUP_DIR/bluetooth_backup_$(date +%Y%m%d_%H%M%S).plist"
    
    if [[ -f "/Library/Preferences/com.apple.Bluetooth.plist" ]]; then
        cp "/Library/Preferences/com.apple.Bluetooth.plist" "$backup_file"
        log_action "Bluetooth configuration backed up to: $backup_file"
        echo "$backup_file"
    else
        log_action "WARNING: Bluetooth preference file not found for backup"
        return 1
    fi
}

# Set Bluetooth state with comprehensive validation
set_bluetooth_state() {
    local desired_state="$1"  # "on" or "off"
    local force_restart="${2:-false}"
    
    # Validate input
    if [[ "$desired_state" != "on" && "$desired_state" != "off" ]]; then
        log_action "ERROR: Invalid state specified. Use 'on' or 'off'"
        return 1
    fi
    
    # Get current state
    local current_state
    current_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    local target_value
    if [[ "$desired_state" == "on" ]]; then
        target_value=1
    else
        target_value=0
    fi
    
    # Check if change is needed
    if [[ "$current_state" == "$target_value" && "$force_restart" == "false" ]]; then
        log_action "Bluetooth already in desired state: $desired_state"
        return 0
    fi
    
    # Create backup before changes
    backup_bluetooth_config
    
    # Set new state
    log_action "Setting Bluetooth state to: $desired_state"
    sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int "$target_value"
    
    # Restart Bluetooth daemon
    restart_bluetooth_daemon
    
    # Wait for changes to propagate
    sleep 5
    
    # Verify the change
    local new_state
    new_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    if [[ "$new_state" == "$target_value" ]]; then
        log_action "✅ Bluetooth successfully set to: $desired_state"
        return 0
    else
        log_action "❌ Failed to set Bluetooth to: $desired_state"
        return 1
    fi
}

# Restart Bluetooth daemon with error handling
restart_bluetooth_daemon() {
    log_action "Restarting Bluetooth daemon..."
    
    # Try modern bluetoothd first
    if pgrep bluetoothd >/dev/null 2>&1; then
        if sudo killall -HUP bluetoothd 2>/dev/null; then
            log_action "Bluetooth daemon (bluetoothd) restarted successfully"
            return 0
        else
            log_action "WARNING: Failed to restart bluetoothd with HUP signal"
        fi
    fi
    
    # Try legacy blued
    if pgrep blued >/dev/null 2>&1; then
        if sudo killall -HUP blued 2>/dev/null; then
            log_action "Bluetooth daemon (blued) restarted successfully"
            return 0
        else
            log_action "WARNING: Failed to restart blued with HUP signal"
        fi
    fi
    
    # Try launchctl approach
    local daemon_service=""
    if launchctl list | grep -q "com.apple.bluetoothd"; then
        daemon_service="com.apple.bluetoothd"
    elif launchctl list | grep -q "com.apple.blued"; then
        daemon_service="com.apple.blued"
    fi
    
    if [[ -n "$daemon_service" ]]; then
        log_action "Attempting launchctl restart for: $daemon_service"
        sudo launchctl stop "$daemon_service" 2>/dev/null
        sleep 2
        sudo launchctl start "$daemon_service" 2>/dev/null
        log_action "Bluetooth service restarted via launchctl"
        return 0
    fi
    
    log_action "ERROR: Could not restart Bluetooth daemon"
    return 1
}

# Monitor Bluetooth connectivity and paired devices
monitor_bluetooth_devices() {
    log_action "Starting Bluetooth device monitoring..."
    
    # Get current power state
    local power_state
    power_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    if [[ "$power_state" != "1" ]]; then
        log_action "Bluetooth is OFF - no devices to monitor"
        return 0
    fi
    
    # Check for system_profiler availability
    if ! command -v system_profiler >/dev/null 2>&1; then
        log_action "WARNING: system_profiler not available for device monitoring"
        return 1
    fi
    
    # Get Bluetooth device information
    local bt_devices
    bt_devices=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -A10 "Devices:" || echo "No devices found")
    
    log_action "Bluetooth devices status:"
    echo "$bt_devices" | while IFS= read -r line; do
        log_action "  $line"
    done
    
    # Count connected devices
    local connected_count
    connected_count=$(echo "$bt_devices" | grep -c "Connected: Yes" || echo "0")
    log_action "Total connected Bluetooth devices: $connected_count"
    
    return 0
}

# Generate comprehensive Bluetooth report
generate_bluetooth_report() {
    local report_file="/tmp/bluetooth_report_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Generating Bluetooth report: $report_file"
    
    {
        echo "{"
        echo "  \"report_type\": \"bluetooth_status\","
        echo "  \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"hostname\": \"$(hostname)\","
        echo "  \"device_info\": $(get_bluetooth_info),"
        
        # System information
        echo "  \"system_info\": {"
        echo "    \"macos_version\": \"$(sw_vers -productVersion)\","
        echo "    \"build_version\": \"$(sw_vers -buildVersion)\","
        echo "    \"hardware_uuid\": \"$(system_profiler SPHardwareDataType | grep 'Hardware UUID' | awk -F': ' '{print $2}' | xargs)\""
        echo "  },"
        
        # Bluetooth preferences
        echo "  \"bluetooth_preferences\": {"
        if [[ -f "/Library/Preferences/com.apple.Bluetooth.plist" ]]; then
            echo "    \"preferences_file_exists\": true,"
            echo "    \"file_size\": $(stat -f%z "/Library/Preferences/com.apple.Bluetooth.plist"),"
            echo "    \"last_modified\": \"$(stat -f%Sm -t%Y-%m-%dT%H:%M:%SZ "/Library/Preferences/com.apple.Bluetooth.plist")\""
        else
            echo "    \"preferences_file_exists\": false"
        fi
        echo "  }"
        echo "}"
    } > "$report_file"
    
    log_action "Bluetooth report generated successfully"
    echo "$report_file"
}

# Security compliance check
check_bluetooth_security() {
    log_action "Performing Bluetooth security compliance check..."
    
    local security_issues=()
    
    # Check if Bluetooth is enabled when it should be disabled
    if [[ -f "$CONFIG_FILE" ]] && grep -q "BLUETOOTH_POLICY=disabled" "$CONFIG_FILE"; then
        local current_state
        current_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
        
        if [[ "$current_state" == "1" ]]; then
            security_issues+=("Bluetooth enabled despite policy requiring disabled state")
        fi
    fi
    
    # Check for Bluetooth discoverability (if system_profiler available)
    if command -v system_profiler >/dev/null 2>&1; then
        local discoverable
        discoverable=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -i "discoverable" || echo "unknown")
        
        if echo "$discoverable" | grep -qi "yes"; then
            security_issues+=("Bluetooth is discoverable - potential security risk")
        fi
    fi
    
    # Report security status
    if [[ ${#security_issues[@]} -eq 0 ]]; then
        log_action "✅ Bluetooth security compliance check passed"
        return 0
    else
        log_action "⚠️  Bluetooth security issues found:"
        for issue in "${security_issues[@]}"; do
            log_action "  - $issue"
        done
        return 1
    fi
}

# Main management function
main() {
    local action="${1:-status}"
    local parameter="$2"
    
    setup_directories
    log_action "MacFleet Bluetooth Management started with action: $action"
    
    case "$action" in
        "on"|"enable")
            set_bluetooth_state "on"
            ;;
        "off"|"disable")
            set_bluetooth_state "off"
            ;;
        "restart"|"reload")
            restart_bluetooth_daemon
            ;;
        "status"|"info")
            get_bluetooth_info | python3 -m json.tool 2>/dev/null || get_bluetooth_info
            ;;
        "monitor")
            monitor_bluetooth_devices
            ;;
        "report")
            generate_bluetooth_report
            ;;
        "security")
            check_bluetooth_security
            ;;
        "backup")
            backup_bluetooth_config
            ;;
        "force-on")
            set_bluetooth_state "on" true
            ;;
        "force-off")
            set_bluetooth_state "off" true
            ;;
        *)
            echo "Usage: $0 {on|off|restart|status|monitor|report|security|backup|force-on|force-off}"
            echo ""
            echo "Commands:"
            echo "  on/enable    - Turn Bluetooth ON"
            echo "  off/disable  - Turn Bluetooth OFF"
            echo "  restart      - Restart Bluetooth daemon"
            echo "  status       - Show detailed Bluetooth status"
            echo "  monitor      - Monitor connected devices"
            echo "  report       - Generate comprehensive report"
            echo "  security     - Run security compliance check"
            echo "  backup       - Backup current configuration"
            echo "  force-on     - Force Bluetooth ON (restart daemon)"
            echo "  force-off    - Force Bluetooth OFF (restart daemon)"
            exit 1
            ;;
    esac
    
    log_action "MacFleet Bluetooth Management completed with action: $action"
}

# Execute main function with all arguments
main "$@"

Quick Management Functions

Simple Status Check

#!/bin/bash

# Quick Bluetooth status check with color output
bluetooth_quick_status() {
    local status
    status=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    case "$status" in
        "1")
            echo "🔵 Bluetooth: ON"
            ;;
        "0")
            echo "⚪ Bluetooth: OFF"
            ;;
        *)
            echo "❓ Bluetooth: UNKNOWN"
            ;;
    esac
}

bluetooth_quick_status

Toggle Bluetooth State

#!/bin/bash

# Toggle Bluetooth between ON and OFF states
toggle_bluetooth() {
    local current_state
    current_state=$(defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState 2>/dev/null)
    
    if [[ "$current_state" == "1" ]]; then
        echo "Bluetooth is ON, turning OFF..."
        sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 0
        sudo killall -HUP bluetoothd 2>/dev/null || sudo killall -HUP blued 2>/dev/null
        echo "✅ Bluetooth turned OFF"
    else
        echo "Bluetooth is OFF, turning ON..."
        sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 1
        sudo killall -HUP bluetoothd 2>/dev/null || sudo killall -HUP blued 2>/dev/null
        echo "✅ Bluetooth turned ON"
    fi
}

toggle_bluetooth

Configuration Templates

Bluetooth Policy Configuration

# /etc/macfleet/bluetooth_config.conf
# MacFleet Bluetooth Management Configuration

# Policy settings
BLUETOOTH_POLICY="enabled"  # enabled, disabled, user_controlled
AUTO_DISABLE_ON_IDLE="false"
IDLE_TIMEOUT_MINUTES="30"

# Security settings
ALLOW_DISCOVERABLE="false"
REQUIRE_PAIRING_CONFIRMATION="true"
LOG_DEVICE_CONNECTIONS="true"

# Monitoring settings
MONITOR_INTERVAL_SECONDS="300"
ALERT_ON_NEW_DEVICES="true"
COMPLIANCE_CHECK_ENABLED="true"

# Backup settings
AUTO_BACKUP_ENABLED="true"
BACKUP_RETENTION_DAYS="30"

Troubleshooting Common Issues

Bluetooth Daemon Not Responding

#!/bin/bash

# Troubleshoot and fix Bluetooth daemon issues
fix_bluetooth_daemon() {
    echo "Diagnosing Bluetooth daemon issues..."
    
    # Check if daemon is running
    if ! pgrep bluetoothd >/dev/null 2>&1 && ! pgrep blued >/dev/null 2>&1; then
        echo "❌ No Bluetooth daemon found running"
        
        # Try to start via launchctl
        if launchctl list | grep -q "com.apple.bluetoothd"; then
            echo "Starting bluetoothd via launchctl..."
            sudo launchctl start com.apple.bluetoothd
        elif launchctl list | grep -q "com.apple.blued"; then
            echo "Starting blued via launchctl..."
            sudo launchctl start com.apple.blued
        else
            echo "❌ Bluetooth service not found in launchctl"
            return 1
        fi
    fi
    
    # Force restart if still having issues
    echo "Force restarting Bluetooth system..."
    sudo pkill -f bluetooth
    sleep 3
    
    # Restart via launchctl
    for service in "com.apple.bluetoothd" "com.apple.blued"; do
        if launchctl list | grep -q "$service"; then
            sudo launchctl stop "$service" 2>/dev/null
            sleep 2
            sudo launchctl start "$service" 2>/dev/null
            echo "Restarted service: $service"
        fi
    done
    
    # Verify recovery
    sleep 5
    if pgrep bluetoothd >/dev/null 2>&1 || pgrep blued >/dev/null 2>&1; then
        echo "✅ Bluetooth daemon recovery successful"
        return 0
    else
        echo "❌ Bluetooth daemon recovery failed"
        return 1
    fi
}

fix_bluetooth_daemon

Reset Bluetooth Configuration

#!/bin/bash

# Reset Bluetooth to factory defaults
reset_bluetooth_config() {
    echo "⚠️  Resetting Bluetooth configuration to defaults..."
    
    # Create backup
    if [[ -f "/Library/Preferences/com.apple.Bluetooth.plist" ]]; then
        cp "/Library/Preferences/com.apple.Bluetooth.plist" "/tmp/bluetooth_backup_$(date +%s).plist"
        echo "Backup created in /tmp/"
    fi
    
    # Stop Bluetooth services
    sudo launchctl stop com.apple.bluetoothd 2>/dev/null
    sudo launchctl stop com.apple.blued 2>/dev/null
    
    # Remove configuration files
    sudo rm -f "/Library/Preferences/com.apple.Bluetooth.plist"
    sudo rm -f "/Library/Preferences/ByHost/com.apple.Bluetooth.*.plist"
    
    # Restart services
    sudo launchctl start com.apple.bluetoothd 2>/dev/null
    sudo launchctl start com.apple.blued 2>/dev/null
    
    # Set default state
    sleep 3
    sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 1
    sudo killall -HUP bluetoothd 2>/dev/null || sudo killall -HUP blued 2>/dev/null
    
    echo "✅ Bluetooth configuration reset completed"
}

# Uncomment to execute
# reset_bluetooth_config

Important Technical Notes

Daemon Management

  • bluetoothd: Modern Bluetooth daemon (macOS 10.10+)
  • blued: Legacy Bluetooth daemon (older macOS versions)
  • killall -HUP: Sends hangup signal to restart daemon gracefully
  • launchctl: Preferred method for service management

Configuration Details

  • File Location: /Library/Preferences/com.apple.Bluetooth
  • Power State Key: ControllerPowerState
  • Values: 1 (ON), 0 (OFF)
  • Persistence: Changes persist across reboots

Security Considerations

  1. Administrative Privileges: All Bluetooth modifications require sudo
  2. Daemon Restart: Changes only take effect after daemon restart
  3. User Impact: Turning off Bluetooth disconnects all paired devices
  4. Policy Compliance: Monitor for unauthorized Bluetooth changes

Best Practices

  1. Always backup configurations before making changes
  2. Test daemon restart methods for your macOS version
  3. Monitor for delays - daemon restart can take several seconds
  4. Implement logging for audit trails and troubleshooting
  5. Use launchctl for more reliable service management
  6. Validate changes after applying modifications
  7. Consider user impact when disabling Bluetooth remotely
  8. Test scripts thoroughly before fleet deployment

Remember to validate all scripts on test devices before deploying across your MacFleet environment, and be aware that Bluetooth changes may take a few minutes to fully propagate through the system.

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.