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.

macOS Update Management

Implement enterprise-grade macOS update management across your MacFleet deployment with automated patch deployment, compliance monitoring, staged rollouts, and comprehensive update policies. This tutorial provides solutions for maintaining security patches and OS currency while minimizing disruption to business operations.

Understanding macOS Update Management

macOS provides several methods for managing operating system updates programmatically:

  • Software Update utility - Command-line tool for checking and installing updates
  • startosinstall - Direct OS installation from installer applications
  • MDM Update Commands - Mobile Device Management integration
  • Configuration Profiles - Policy-based update control
  • Apple Software Lookup Service - Update availability checking

Basic Update Operations

List Available Updates

#!/bin/bash

# List all available OS versions for installation
softwareupdate --list-full-installers | grep 'macOS' | awk '{print ++count " " $0}'

Download OS Installer

#!/bin/bash

# Fetch specific OS version installer
softwareupdate --fetch-full-installer --full-installer-version 12.1

echo "OS installer downloaded successfully"

Install OS Update

#!/bin/bash

# Basic OS update installation
osVersion="$1"
majorVersion=$(echo $osVersion | cut -d "." -f 1)
minorVersion=$(echo $osVersion | cut -d "." -f 2)

if [ $majorVersion == "12" ]; then
    installerPath="Install macOS Monterey.app"
elif [ $majorVersion == "11" ]; then
    installerPath="Install macOS Big Sur.app"
elif [ $minorVersion == "15"* ]; then
    installerPath="Install macOS Catalina.app"
fi

fullPath="/Applications/$installerPath/Contents/Resources/startosinstall"
softwareupdate --fetch-full-installer --full-installer-version $osVersion
echo <Password> | "$fullPath" --agreetolicense --forcequitapps --nointeraction --user <Username> --stdinpass

Enterprise Update Management System

Comprehensive Update Management Tool

#!/bin/bash

# MacFleet Enterprise macOS Update Management Tool
# Automated patch deployment and compliance monitoring

# Configuration
CONFIG_FILE="/etc/macfleet/update_policy.conf"
LOG_FILE="/var/log/macfleet_updates.log"
CACHE_DIR="/Library/MacFleet/Updates"
REPORT_DIR="/var/log/macfleet_reports"

# Create directories
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$CACHE_DIR" "$REPORT_DIR"

# Default update policy
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# MacFleet macOS Update Management Policy
# Version: 2.0

# Update Enforcement
ENFORCE_SECURITY_UPDATES=true
ALLOW_MAJOR_OS_UPDATES=false
AUTO_INSTALL_SECURITY_PATCHES=true
DEFER_MAJOR_UPDATES_DAYS=30

# Scheduling Configuration
UPDATE_CHECK_INTERVAL=86400  # 24 hours
MAINTENANCE_WINDOW_START="02:00"
MAINTENANCE_WINDOW_END="06:00"
WEEKEND_UPDATES_ALLOWED=true
BUSINESS_HOURS_UPDATES=false

# Deployment Strategy
STAGED_ROLLOUT=true
PILOT_GROUP_PERCENTAGE=10
PRODUCTION_DELAY_DAYS=7
EMERGENCY_PATCH_IMMEDIATE=true

# System Requirements
MIN_BATTERY_PERCENTAGE=50
MIN_FREE_SPACE_GB=20
REQUIRE_AC_POWER=true
MAX_REBOOT_ATTEMPTS=3

# Notification Settings
NOTIFY_USERS_BEFORE_UPDATE=true
NOTIFICATION_LEAD_TIME_HOURS=24
FORCE_UPDATE_AFTER_DEFERRALS=5
SEND_COMPLETION_REPORTS=true

# Compatibility Settings
EXCLUDE_BETA_UPDATES=true
VALIDATE_APP_COMPATIBILITY=true
BACKUP_BEFORE_MAJOR_UPDATE=true
EOF

# Source configuration
source "$CONFIG_FILE" 2>/dev/null || true

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

# Get current macOS version
get_current_version() {
    sw_vers -productVersion
}

# Get available updates
get_available_updates() {
    echo "=== Available Updates ==="
    
    # Check for software updates
    local updates
    updates=$(softwareupdate --list 2>/dev/null)
    
    if echo "$updates" | grep -q "No new software available"; then
        echo "✅ System is up to date"
        return 0
    else
        echo "Available updates:"
        echo "$updates"
        return 1
    fi
}

# Get available OS installers
get_available_installers() {
    echo "=== Available OS Installers ==="
    
    # List full installers
    local installers
    installers=$(softwareupdate --list-full-installers 2>/dev/null)
    
    if [[ -n "$installers" ]]; then
        echo "$installers" | grep 'macOS' | awk '{print ++count " " $0}'
    else
        echo "No OS installers available"
    fi
}

# Check system readiness for updates
check_update_readiness() {
    echo "=== Update Readiness Check ==="
    local issues=0
    local warnings=0
    
    # Check battery level
    local battery_level
    if command -v pmset >/dev/null; then
        battery_level=$(pmset -g batt | grep -Eo "\d+%" | tr -d '%' | head -1)
        
        if [[ -n "$battery_level" && $battery_level -lt $MIN_BATTERY_PERCENTAGE ]]; then
            echo "❌ Battery level too low: ${battery_level}% (min: ${MIN_BATTERY_PERCENTAGE}%)"
            ((issues++))
        else
            echo "✅ Battery level adequate: ${battery_level:-AC Power}%"
        fi
    fi
    
    # Check AC power if required
    if [[ "$REQUIRE_AC_POWER" == "true" ]]; then
        local ac_power
        ac_power=$(pmset -g ps | grep "AC Power" || echo "")
        
        if [[ -z "$ac_power" ]]; then
            echo "❌ AC power required but not connected"
            ((issues++))
        else
            echo "✅ AC power connected"
        fi
    fi
    
    # Check free disk space
    local free_space_gb
    free_space_gb=$(df / | awk 'NR==2 {print int($4/1024/1024)}')
    
    if [[ $free_space_gb -lt $MIN_FREE_SPACE_GB ]]; then
        echo "❌ Insufficient disk space: ${free_space_gb}GB (min: ${MIN_FREE_SPACE_GB}GB)"
        ((issues++))
    else
        echo "✅ Sufficient disk space: ${free_space_gb}GB"
    fi
    
    # Check if system is in maintenance window
    local current_time
    current_time=$(date '+%H:%M')
    
    if [[ "$current_time" > "$MAINTENANCE_WINDOW_START" && "$current_time" < "$MAINTENANCE_WINDOW_END" ]]; then
        echo "✅ Within maintenance window"
    else
        echo "⚠️  Outside maintenance window (current: $current_time)"
        ((warnings++))
    fi
    
    # Check if weekend updates are allowed
    local day_of_week
    day_of_week=$(date '+%u')  # 1=Monday, 7=Sunday
    
    if [[ $day_of_week -gt 5 ]] && [[ "$WEEKEND_UPDATES_ALLOWED" != "true" ]]; then
        echo "❌ Weekend updates not allowed"
        ((issues++))
    fi
    
    echo "Readiness summary: $issues issues, $warnings warnings"
    return $issues
}

# Install security updates
install_security_updates() {
    echo "=== Installing Security Updates ==="
    
    if [[ "$AUTO_INSTALL_SECURITY_PATCHES" != "true" ]]; then
        echo "Security update auto-installation disabled"
        return 0
    fi
    
    # Check readiness
    if ! check_update_readiness >/dev/null; then
        echo "❌ System not ready for updates"
        return 1
    fi
    
    # Install recommended updates
    echo "Installing security and recommended updates..."
    log_action "Starting security update installation"
    
    # Use softwareupdate to install recommended updates
    if softwareupdate --install --recommended --verbose; then
        echo "✅ Security updates installed successfully"
        log_action "Security updates installed successfully"
        
        # Check if restart is required
        if softwareupdate --list | grep -q "restart"; then
            echo "⚠️  System restart required"
            log_action "System restart required after security updates"
        fi
        
        return 0
    else
        echo "❌ Failed to install security updates"
        log_action "FAILED: Security update installation"
        return 1
    fi
}

# Download OS installer
download_os_installer() {
    local target_version="$1"
    
    echo "=== Downloading OS Installer ==="
    echo "Target version: $target_version"
    
    # Validate version format
    if [[ ! "$target_version" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
        echo "❌ Invalid version format: $target_version"
        return 1
    fi
    
    # Download installer
    echo "Downloading macOS $target_version installer..."
    log_action "Downloading macOS installer: $target_version"
    
    if softwareupdate --fetch-full-installer --full-installer-version "$target_version"; then
        echo "✅ macOS installer downloaded successfully"
        log_action "macOS installer downloaded: $target_version"
        
        # Verify installer exists
        local installer_path
        installer_path=$(find /Applications -name "Install macOS*.app" -path "*$target_version*" 2>/dev/null | head -1)
        
        if [[ -n "$installer_path" && -d "$installer_path" ]]; then
            echo "Installer location: $installer_path"
            return 0
        else
            # Check for installer by major version
            local major_version
            major_version=$(echo "$target_version" | cut -d'.' -f1)
            
            case "$major_version" in
                "15")
                    installer_path="/Applications/Install macOS Sequoia.app"
                    ;;
                "14")
                    installer_path="/Applications/Install macOS Sonoma.app"
                    ;;
                "13")
                    installer_path="/Applications/Install macOS Ventura.app"
                    ;;
                "12")
                    installer_path="/Applications/Install macOS Monterey.app"
                    ;;
                "11")
                    installer_path="/Applications/Install macOS Big Sur.app"
                    ;;
                *)
                    echo "❌ Unknown macOS version: $target_version"
                    return 1
                    ;;
            esac
            
            if [[ -d "$installer_path" ]]; then
                echo "Installer found: $installer_path"
                return 0
            else
                echo "❌ Installer not found after download"
                return 1
            fi
        fi
    else
        echo "❌ Failed to download macOS installer"
        log_action "FAILED: macOS installer download for $target_version"
        return 1
    fi
}

# Install major OS update
install_major_update() {
    local target_version="$1"
    local admin_user="$2"
    local admin_password="$3"
    
    echo "=== Installing Major OS Update ==="
    echo "Target version: $target_version"
    echo "Admin user: $admin_user"
    
    if [[ "$ALLOW_MAJOR_OS_UPDATES" != "true" ]]; then
        echo "❌ Major OS updates not allowed by policy"
        return 1
    fi
    
    # Check readiness
    if ! check_update_readiness; then
        echo "❌ System not ready for major update"
        return 1
    fi
    
    # Find installer
    local installer_path
    local major_version
    major_version=$(echo "$target_version" | cut -d'.' -f1)
    
    case "$major_version" in
        "15")
            installer_path="/Applications/Install macOS Sequoia.app"
            ;;
        "14")
            installer_path="/Applications/Install macOS Sonoma.app"
            ;;
        "13")
            installer_path="/Applications/Install macOS Ventura.app"
            ;;
        "12")
            installer_path="/Applications/Install macOS Monterey.app"
            ;;
        "11")
            installer_path="/Applications/Install macOS Big Sur.app"
            ;;
        *)
            echo "❌ Unsupported macOS version: $target_version"
            return 1
            ;;
    esac
    
    if [[ ! -d "$installer_path" ]]; then
        echo "Installer not found, downloading..."
        if ! download_os_installer "$target_version"; then
            return 1
        fi
    fi
    
    # Prepare installation command
    local install_cmd="$installer_path/Contents/Resources/startosinstall"
    local install_args="--agreetolicense --forcequitapps --nointeraction"
    
    # Check if Apple Silicon Mac (requires credentials)
    if system_profiler SPHardwareDataType | grep -q "Apple M"; then
        if [[ -z "$admin_user" || -z "$admin_password" ]]; then
            echo "❌ Apple Silicon Mac requires admin credentials"
            return 1
        fi
        install_args="$install_args --user $admin_user --stdinpass"
    fi
    
    echo "Starting macOS installation..."
    log_action "Starting major OS update to $target_version"
    
    # Execute installation
    if [[ -n "$admin_password" ]]; then
        echo "$admin_password" | "$install_cmd" $install_args
    else
        "$install_cmd" $install_args
    fi
    
    local result=$?
    
    if [[ $result -eq 0 ]]; then
        echo "✅ macOS update initiated successfully"
        log_action "macOS update initiated successfully to $target_version"
        echo "⚠️  System will restart to complete installation"
    else
        echo "❌ Failed to initiate macOS update (exit code: $result)"
        log_action "FAILED: macOS update initiation to $target_version (exit code: $result)"
    fi
    
    return $result
}

# Generate update compliance report
generate_update_report() {
    local report_file="$REPORT_DIR/update_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Generating Update Compliance Report ==="
    
    # Get current system information
    local current_version
    current_version=$(sw_vers -productVersion)
    local build_version
    build_version=$(sw_vers -buildVersion)
    local hardware_model
    hardware_model=$(system_profiler SPHardwareDataType | grep "Model Identifier" | awk -F: '{print $2}' | xargs)
    
    # Check for available updates
    local updates_available="false"
    local security_updates_available="false"
    
    if ! softwareupdate --list 2>/dev/null | grep -q "No new software available"; then
        updates_available="true"
        
        if softwareupdate --list 2>/dev/null | grep -i "security\|recommended"; then
            security_updates_available="true"
        fi
    fi
    
    # Calculate days since last update
    local last_update_date
    last_update_date=$(system_profiler SPInstallHistoryDataType | grep "Install Date" | head -1 | awk -F: '{print $2}' | xargs)
    local days_since_update="unknown"
    
    if [[ -n "$last_update_date" ]]; then
        local last_update_epoch
        last_update_epoch=$(date -j -f "%m/%d/%y" "$last_update_date" "+%s" 2>/dev/null || echo "0")
        local current_epoch
        current_epoch=$(date "+%s")
        days_since_update=$(( (current_epoch - last_update_epoch) / 86400 ))
    fi
    
    # Create JSON report
    cat > "$report_file" << EOF
{
  "report_type": "update_compliance",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "device_info": {
    "hostname": "$(hostname)",
    "serial_number": "$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)",
    "hardware_model": "$hardware_model",
    "current_os_version": "$current_version",
    "build_version": "$build_version"
  },
  "update_status": {
    "updates_available": $updates_available,
    "security_updates_available": $security_updates_available,
    "days_since_last_update": $days_since_update,
    "last_update_date": "$last_update_date",
    "auto_update_enabled": $(defaults read /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled 2>/dev/null || echo false)
  },
  "policy_compliance": {
    "security_updates_enforced": $ENFORCE_SECURITY_UPDATES,
    "major_updates_allowed": $ALLOW_MAJOR_OS_UPDATES,
    "auto_install_enabled": $AUTO_INSTALL_SECURITY_PATCHES,
    "staged_rollout_enabled": $STAGED_ROLLOUT
  },
  "system_readiness": {
    "sufficient_battery": true,
    "ac_power_connected": $(pmset -g ps | grep -q "AC Power" && echo true || echo false),
    "sufficient_disk_space": true,
    "in_maintenance_window": false
  }
}
EOF
    
    echo "Update compliance report saved to: $report_file"
    log_action "Update compliance report generated: $report_file"
}

# Main function with argument handling
main() {
    log_action "=== MacFleet Update Management Tool Started ==="
    
    case "${1:-status}" in
        "check")
            get_available_updates
            ;;
        "security")
            install_security_updates
            ;;
        "download")
            download_os_installer "$2"
            ;;
        "install")
            install_major_update "$2" "$3" "$4"
            ;;
        "readiness")
            check_update_readiness
            ;;
        "installers")
            get_available_installers
            ;;
        "report")
            generate_update_report
            ;;
        "status"|*)
            echo "Current macOS version: $(get_current_version)"
            get_available_updates
            ;;
    esac
    
    log_action "=== Update management operation completed ==="
}

# Execute main function
main "$@"

Advanced Update Management

Staged Rollout Management

#!/bin/bash

# Staged rollout management for enterprise deployments
manage_staged_rollout() {
    local update_version="$1"
    local deployment_stage="${2:-pilot}"
    
    echo "=== Staged Rollout Management ==="
    echo "Update version: $update_version"
    echo "Deployment stage: $deployment_stage"
    
    # Define device groups
    local device_serial
    device_serial=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)
    
    # Calculate hash for consistent group assignment
    local hash_value
    hash_value=$(echo "$device_serial" | md5 | cut -c1-2)
    local numeric_hash
    numeric_hash=$(printf "%d" "0x$hash_value")
    local group_percentage
    group_percentage=$((numeric_hash % 100))
    
    case "$deployment_stage" in
        "pilot")
            if [[ $group_percentage -lt $PILOT_GROUP_PERCENTAGE ]]; then
                echo "✅ Device selected for pilot deployment"
                log_action "Device included in pilot group for $update_version"
                return 0
            else
                echo "⏳ Device not in pilot group, waiting for production rollout"
                return 1
            fi
            ;;
        "production")
            echo "✅ Device eligible for production deployment"
            log_action "Device included in production rollout for $update_version"
            return 0
            ;;
        "emergency")
            echo "🚨 Emergency deployment - bypassing staging"
            log_action "Emergency deployment initiated for $update_version"
            return 0
            ;;
        *)
            echo "❌ Unknown deployment stage: $deployment_stage"
            return 1
            ;;
    esac
}

# Usage example:
# manage_staged_rollout "14.2.1" "pilot"

Update Compatibility Checking

#!/bin/bash

# Check application compatibility before major updates
check_app_compatibility() {
    local target_version="$1"
    
    echo "=== Application Compatibility Check ==="
    
    if [[ "$VALIDATE_APP_COMPATIBILITY" != "true" ]]; then
        echo "App compatibility checking disabled"
        return 0
    fi
    
    local incompatible_apps=()
    
    # Check for 32-bit applications (not supported in macOS 10.15+)
    local target_major
    target_major=$(echo "$target_version" | cut -d'.' -f1)
    
    if [[ $target_major -ge 10 ]]; then
        echo "Checking for 32-bit applications..."
        
        # Use system_profiler to find 32-bit apps
        local bit32_apps
        bit32_apps=$(system_profiler SPApplicationsDataType | grep -B1 -A1 "64-Bit (Intel): No" | grep "Location:" | awk -F: '{print $2}' | xargs)
        
        if [[ -n "$bit32_apps" ]]; then
            echo "⚠️  Found 32-bit applications:"
            echo "$bit32_apps"
            incompatible_apps+=("32-bit applications")
        fi
    fi
    
    # Check for known incompatible applications
    local known_incompatible=(
        "/Applications/Adobe CS6"
        "/Applications/Microsoft Office 2011"
        "/Applications/Final Cut Pro 7"
    )
    
    for app_path in "${known_incompatible[@]}"; do
        if [[ -d "$app_path" ]]; then
            echo "⚠️  Found known incompatible app: $app_path"
            incompatible_apps+=("$(basename "$app_path")")
        fi
    done
    
    # Generate compatibility report
    if [[ ${#incompatible_apps[@]} -eq 0 ]]; then
        echo "✅ No compatibility issues detected"
        return 0
    else
        echo "❌ Compatibility issues found:"
        printf '  - %s\n' "${incompatible_apps[@]}"
        
        # Log compatibility issues
        log_action "App compatibility issues found for $target_version: ${incompatible_apps[*]}"
        return 1
    fi
}

check_app_compatibility "14.0"

Automated Backup Before Updates

#!/bin/bash

# Create system backup before major updates
create_pre_update_backup() {
    local backup_destination="${1:-/Volumes/Backup}"
    
    echo "=== Pre-Update Backup ==="
    
    if [[ "$BACKUP_BEFORE_MAJOR_UPDATE" != "true" ]]; then
        echo "Pre-update backup disabled"
        return 0
    fi
    
    # Check backup destination
    if [[ ! -d "$backup_destination" ]]; then
        echo "❌ Backup destination not available: $backup_destination"
        return 1
    fi
    
    # Create Time Machine backup
    echo "Creating Time Machine backup..."
    if tmutil startbackup --auto --block; then
        echo "✅ Time Machine backup completed"
        log_action "Pre-update Time Machine backup completed"
    else
        echo "⚠️  Time Machine backup failed, continuing with update"
        log_action "WARNING: Pre-update Time Machine backup failed"
    fi
    
    # Create system configuration backup
    local config_backup="$backup_destination/macfleet_config_$(date +%Y%m%d_%H%M%S).tar.gz"
    
    echo "Creating configuration backup..."
    if tar -czf "$config_backup" \
        /etc/macfleet \
        /Library/Preferences \
        /System/Library/LaunchDaemons/com.macfleet.* \
        2>/dev/null; then
        echo "✅ Configuration backup created: $config_backup"
        log_action "Configuration backup created: $config_backup"
    else
        echo "⚠️  Configuration backup failed"
        log_action "WARNING: Configuration backup failed"
    fi
    
    return 0
}

create_pre_update_backup

Monitoring and Compliance

Update Compliance Monitoring

#!/bin/bash

# Monitor update compliance across fleet
monitor_update_compliance() {
    echo "=== Update Compliance Monitoring ==="
    
    local current_version
    current_version=$(sw_vers -productVersion)
    
    # Check against security baselines
    local security_baseline="14.2.1"  # Example baseline
    
    if [[ "$(printf '%s\n' "$security_baseline" "$current_version" | sort -V | head -1)" != "$security_baseline" ]]; then
        echo "❌ Below security baseline (current: $current_version, required: $security_baseline)"
        log_action "COMPLIANCE VIOLATION: Below security baseline $security_baseline"
        
        # Trigger remediation if enabled
        if [[ "$ENFORCE_SECURITY_UPDATES" == "true" ]]; then
            echo "Initiating automatic remediation..."
            install_security_updates
        fi
    else
        echo "✅ Meets security baseline requirements"
    fi
    
    # Check for overdue updates
    local last_check
    last_check=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate LastSuccessfulDate 2>/dev/null || echo "")
    
    if [[ -n "$last_check" ]]; then
        local days_since_check
        days_since_check=$(( ($(date +%s) - $(date -j -f "%Y-%m-%d %H:%M:%S %z" "$last_check" +%s 2>/dev/null || echo 0)) / 86400 ))
        
        if [[ $days_since_check -gt 7 ]]; then
            echo "⚠️  Updates not checked for $days_since_check days"
            log_action "WARNING: Updates not checked for $days_since_check days"
        fi
    fi
}

monitor_update_compliance

Emergency Patch Deployment

#!/bin/bash

# Emergency patch deployment for critical security updates
deploy_emergency_patch() {
    local patch_version="$1"
    local override_policies="${2:-false}"
    
    echo "=== Emergency Patch Deployment ==="
    echo "Patch version: $patch_version"
    echo "Override policies: $override_policies"
    
    log_action "EMERGENCY: Deploying critical patch $patch_version"
    
    # Override normal restrictions for emergency patches
    if [[ "$override_policies" == "true" ]]; then
        # Temporarily modify configuration
        local original_config
        original_config=$(cat "$CONFIG_FILE")
        
        # Emergency configuration
        cat > "$CONFIG_FILE" << 'EOF'
ENFORCE_SECURITY_UPDATES=true
AUTO_INSTALL_SECURITY_PATCHES=true
EMERGENCY_PATCH_IMMEDIATE=true
REQUIRE_AC_POWER=false
MIN_BATTERY_PERCENTAGE=20
BUSINESS_HOURS_UPDATES=true
EOF
        
        # Install emergency patch
        if install_security_updates; then
            echo "✅ Emergency patch deployed successfully"
            log_action "Emergency patch $patch_version deployed successfully"
        else
            echo "❌ Emergency patch deployment failed"
            log_action "CRITICAL: Emergency patch $patch_version deployment FAILED"
        fi
        
        # Restore original configuration
        echo "$original_config" > "$CONFIG_FILE"
    else
        # Standard emergency deployment
        install_security_updates
    fi
}

# Example usage:
# deploy_emergency_patch "14.2.1" "true"

Important Configuration Notes

macOS Update Tools

  • softwareupdate - Command-line Software Update utility
  • startosinstall - Direct OS installation tool
  • system_profiler - System information and update history
  • tmutil - Time Machine backup utility
  • pmset - Power management settings

Apple Silicon Considerations

  • Admin credentials required - Updates need user authentication
  • Secure Boot policies - May affect update installation
  • Recovery mode options - Different from Intel Macs
  • Reduced kernel extensions - System extension model

Best Practices for Enterprise

  1. Staged Deployment Strategy

    • Test updates on pilot group first
    • Monitor for issues before full rollout
    • Maintain rollback capabilities
  2. Compliance Management

    • Define security baselines
    • Monitor update status regularly
    • Automate compliance reporting
  3. Risk Mitigation

    • Backup before major updates
    • Test application compatibility
    • Plan for emergency patches
  4. User Communication

    • Notify users of scheduled updates
    • Provide clear maintenance windows
    • Offer deferral options within policy limits

Troubleshooting Common Issues

  • Insufficient disk space - Clean up before updates or increase storage
  • Power requirements - Ensure AC power for major updates
  • Network connectivity - Verify access to Apple's update servers
  • Authentication failures - Check admin credentials on Apple Silicon
  • Installation failures - Review system logs and compatibility

Remember to test update procedures thoroughly in a non-production environment before deploying across your entire MacFleet.

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.