Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Aviso importante

Los ejemplos de código y scripts proporcionados en estos tutoriales son solo para propósitos educativos. Macfleet no es responsable de ningún problema, daño o vulnerabilidad de seguridad que pueda surgir del uso, modificación o implementación de estos ejemplos. Siempre revisa y prueba el código en un entorno seguro antes de usarlo en sistemas de producción.

Sleep and Power Management for macOS

Implement enterprise-grade sleep and power management across your MacFleet deployment with automated power policies, energy optimization, compliance monitoring, and comprehensive fleet-wide management. This tutorial provides solutions for maintaining optimal power efficiency while ensuring security and operational requirements are met.

Understanding macOS Power Management

macOS provides several power management tools and mechanisms:

  • pmset - Primary power management settings tool
  • caffeinate - Prevent system sleep for specific operations
  • systemsetup - System-wide power configuration
  • Energy Saver - GUI power management interface
  • Power Assertions - Application-level sleep prevention

Basic Power Management Operations

Configure System Sleep Timer

#!/bin/bash

# Set system sleep timer to 15 minutes
sudo pmset sleep 15

Configure Display Sleep Timer

#!/bin/bash

# Set display sleep timer to 15 minutes
sudo pmset displaysleep 15

Schedule Wake Events

#!/bin/bash

# Schedule wake every day at 9:00 AM
sudo pmset repeat wakeorpoweron MTWRFSU 9:00:00

Prevent Sleep for Specific Period

#!/bin/bash

# Prevent system sleep for 300 seconds
caffeinate -u -t 300

Check System Sleep Settings

#!/bin/bash

# Check current sleep idle time
sudo systemsetup -getcomputersleep

Disable System Sleep

#!/bin/bash

# Turn off system sleep
sudo systemsetup -setcomputersleep Never

Enable Restart on Freeze

#!/bin/bash

# Restart automatically on system freeze
systemsetup -setrestartfreeze on

Enterprise Power Management System

Comprehensive Power Management Tool

#!/bin/bash

# MacFleet Enterprise Sleep and Power Management Tool
# Advanced power policies and energy optimization

# Configuration
CONFIG_FILE="/etc/macfleet/power_policy.conf"
LOG_FILE="/var/log/macfleet_power.log"
POLICIES_DIR="/Library/MacFleet/PowerPolicies"
AUDIT_LOG="/var/log/macfleet_power_audit.log"

# Create directories
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$POLICIES_DIR" "$(dirname "$AUDIT_LOG")"

# Default power management policy
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# MacFleet Enterprise Power Management Policy
# Version: 2.0

# Power Policy Enforcement
ENFORCE_POWER_POLICIES=true
AUTO_APPLY_POLICIES=true
POWER_PROFILE="corporate_standard"
ENERGY_OPTIMIZATION=true
COMPLIANCE_MONITORING=true

# Sleep Settings (minutes)
SYSTEM_SLEEP_AC=30
SYSTEM_SLEEP_BATTERY=15
DISPLAY_SLEEP_AC=15
DISPLAY_SLEEP_BATTERY=5
DISK_SLEEP_AC=10
DISK_SLEEP_BATTERY=5

# Wake and Power Events
WAKE_ON_LAN=true
WAKE_ON_ADMINISTRATIVE_ACCESS=true
AUTOMATIC_RESTART_ON_POWER_LOSS=true
AUTOMATIC_RESTART_ON_FREEZE=true
SCHEDULED_WAKE_ENABLED=true
SCHEDULED_SLEEP_ENABLED=true

# Business Hours Configuration
BUSINESS_HOURS_START="09:00"
BUSINESS_HOURS_END="18:00"
BUSINESS_DAYS="MTWRF"
WEEKEND_POWER_PROFILE="energy_saver"
AFTER_HOURS_POWER_PROFILE="security_focused"

# Security and Maintenance
SECURE_VIRTUAL_MEMORY=true
DESTROY_FILEVAULT_KEYS_ON_STANDBY=true
HIBERNATE_MODE=3
STANDBY_DELAY=10800
AUTOPOWEROFF_ENABLED=true
AUTOPOWEROFF_DELAY=14400

# Energy and Performance
PROCESSOR_SPEED_REDUCTION=false
REDUCE_BRIGHTNESS_BATTERY=true
DISABLE_POWER_BUTTON_SLEEP=false
PREVENT_SLEEP_DURING_PRESENTATIONS=true
THERMAL_MANAGEMENT=true

# Monitoring and Reporting
POWER_EVENT_LOGGING=true
ENERGY_USAGE_MONITORING=true
BATTERY_HEALTH_MONITORING=true
POWER_ASSERTION_TRACKING=true
AUTOMATED_REPORTING=true

# Compliance Settings
REGULATORY_COMPLIANCE="ENERGY_STAR"
CARBON_FOOTPRINT_TRACKING=true
SUSTAINABILITY_REPORTING=true
POWER_AUDIT_TRAILS=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"
}

# Audit logging function
audit_log() {
    local action="$1"
    local result="$2"
    local details="$3"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ACTION:$action RESULT:$result DETAILS:$details USER:$(whoami)" >> "$AUDIT_LOG"
}

# Get current power settings
get_power_status() {
    echo "=== Current Power Management Status ==="
    
    # System-wide power settings
    echo "System Power Settings:"
    pmset -g 2>/dev/null || echo "  Power settings unavailable"
    
    echo -e "\nCurrent Power Source:"
    pmset -g ps 2>/dev/null | head -1
    
    echo -e "\nSleep Timers:"
    echo "  System Sleep (AC): $(pmset -g | grep -E '^\s*sleep\s' | awk '{print $2}') minutes"
    echo "  Display Sleep (AC): $(pmset -g | grep -E '^\s*displaysleep\s' | awk '{print $2}') minutes"
    echo "  Disk Sleep (AC): $(pmset -g | grep -E '^\s*disksleep\s' | awk '{print $2}') minutes"
    
    echo -e "\nPower Assertions:"
    pmset -g assertions 2>/dev/null | grep -E "(PreventUserIdleSystemSleep|PreventUserIdleDisplaySleep)" | head -5
    
    echo -e "\nThermal State:"
    pmset -g thermstate 2>/dev/null | head -3
    
    echo -e "\nBattery Information:"
    if system_profiler SPPowerDataType 2>/dev/null | grep -q "Battery Information"; then
        system_profiler SPPowerDataType | grep -A 10 "Battery Information" | head -10
    else
        echo "  No battery information available (Desktop Mac)"
    fi
    
    return 0
}

# Apply enterprise power profile
apply_power_profile() {
    local profile="${1:-$POWER_PROFILE}"
    
    echo "=== Applying Enterprise Power Profile: $profile ==="
    
    case "$profile" in
        "corporate_standard")
            apply_corporate_standard_profile
            ;;
        "energy_saver")
            apply_energy_saver_profile
            ;;
        "high_performance")
            apply_high_performance_profile
            ;;
        "security_focused")
            apply_security_focused_profile
            ;;
        "presentation_mode")
            apply_presentation_mode_profile
            ;;
        "kiosk_mode")
            apply_kiosk_mode_profile
            ;;
        *)
            echo "Unknown power profile: $profile"
            echo "Using corporate_standard profile as fallback"
            apply_corporate_standard_profile
            ;;
    esac
    
    # Apply common security settings
    apply_security_settings
    
    # Configure scheduled events
    configure_scheduled_events
    
    echo "✅ Power profile '$profile' applied successfully"
    log_action "Power profile applied: $profile"
    audit_log "POWER_PROFILE" "APPLIED" "Profile: $profile"
    
    return 0
}

# Corporate standard power profile
apply_corporate_standard_profile() {
    echo "=== Configuring Corporate Standard Profile ==="
    
    # AC Power settings
    sudo pmset -c sleep "$SYSTEM_SLEEP_AC" 2>/dev/null
    sudo pmset -c displaysleep "$DISPLAY_SLEEP_AC" 2>/dev/null
    sudo pmset -c disksleep "$DISK_SLEEP_AC" 2>/dev/null
    
    # Battery settings (if applicable)
    sudo pmset -b sleep "$SYSTEM_SLEEP_BATTERY" 2>/dev/null
    sudo pmset -b displaysleep "$DISPLAY_SLEEP_BATTERY" 2>/dev/null
    sudo pmset -b disksleep "$DISK_SLEEP_BATTERY" 2>/dev/null
    
    # Wake settings
    if [[ "$WAKE_ON_LAN" == "true" ]]; then
        sudo pmset -a womp 1 2>/dev/null
    fi
    
    if [[ "$WAKE_ON_ADMINISTRATIVE_ACCESS" == "true" ]]; then
        sudo pmset -a acwake 1 2>/dev/null
    fi
    
    # Restart settings
    if [[ "$AUTOMATIC_RESTART_ON_POWER_LOSS" == "true" ]]; then
        sudo pmset -a autorestart 1 2>/dev/null
    fi
    
    if [[ "$AUTOMATIC_RESTART_ON_FREEZE" == "true" ]]; then
        sudo systemsetup -setrestartfreeze on 2>/dev/null
    fi
    
    echo "Corporate standard profile configured"
    log_action "Corporate standard power profile applied"
}

# Energy saver profile
apply_energy_saver_profile() {
    echo "=== Configuring Energy Saver Profile ==="
    
    # Aggressive power saving
    sudo pmset -c sleep 10 2>/dev/null
    sudo pmset -c displaysleep 5 2>/dev/null
    sudo pmset -c disksleep 5 2>/dev/null
    
    sudo pmset -b sleep 5 2>/dev/null
    sudo pmset -b displaysleep 2 2>/dev/null
    sudo pmset -b disksleep 3 2>/dev/null
    
    # Enable power-saving features
    sudo pmset -a reducebright 1 2>/dev/null
    sudo pmset -a lessbright 1 2>/dev/null
    
    echo "Energy saver profile configured"
    log_action "Energy saver power profile applied"
}

# High performance profile
apply_high_performance_profile() {
    echo "=== Configuring High Performance Profile ==="
    
    # Minimal sleep settings
    sudo pmset -c sleep 60 2>/dev/null
    sudo pmset -c displaysleep 30 2>/dev/null
    sudo pmset -c disksleep 30 2>/dev/null
    
    sudo pmset -b sleep 30 2>/dev/null
    sudo pmset -b displaysleep 15 2>/dev/null
    sudo pmset -b disksleep 15 2>/dev/null
    
    # Disable power-saving features
    sudo pmset -a reducebright 0 2>/dev/null
    sudo pmset -a lessbright 0 2>/dev/null
    
    echo "High performance profile configured"
    log_action "High performance power profile applied"
}

# Security focused profile
apply_security_focused_profile() {
    echo "=== Configuring Security Focused Profile ==="
    
    # Short sleep timers for security
    sudo pmset -c sleep 5 2>/dev/null
    sudo pmset -c displaysleep 3 2>/dev/null
    sudo pmset -c disksleep 5 2>/dev/null
    
    sudo pmset -b sleep 3 2>/dev/null
    sudo pmset -b displaysleep 1 2>/dev/null
    sudo pmset -b disksleep 3 2>/dev/null
    
    # Enhanced security settings
    sudo pmset -a destroyfvkeyonstandby 1 2>/dev/null
    sudo pmset -a hibernatemode 25 2>/dev/null
    
    echo "Security focused profile configured"
    log_action "Security focused power profile applied"
}

# Presentation mode profile
apply_presentation_mode_profile() {
    echo "=== Configuring Presentation Mode Profile ==="
    
    # Prevent sleep during presentations
    sudo pmset -c sleep 0 2>/dev/null
    sudo pmset -c displaysleep 0 2>/dev/null
    
    # Keep system active
    sudo pmset -a lidwake 1 2>/dev/null
    sudo pmset -a acwake 1 2>/dev/null
    
    echo "Presentation mode profile configured"
    log_action "Presentation mode power profile applied"
}

# Kiosk mode profile
apply_kiosk_mode_profile() {
    echo "=== Configuring Kiosk Mode Profile ==="
    
    # Never sleep settings for kiosk devices
    sudo pmset -c sleep 0 2>/dev/null
    sudo pmset -c displaysleep 0 2>/dev/null
    sudo pmset -c disksleep 0 2>/dev/null
    
    # Ensure system stays active
    sudo pmset -a womp 1 2>/dev/null
    sudo pmset -a autorestart 1 2>/dev/null
    
    echo "Kiosk mode profile configured"
    log_action "Kiosk mode power profile applied"
}

# Apply security-specific power settings
apply_security_settings() {
    echo "=== Applying Security Power Settings ==="
    
    if [[ "$SECURE_VIRTUAL_MEMORY" == "true" ]]; then
        sudo pmset -a securevm 1 2>/dev/null
        echo "✅ Secure virtual memory enabled"
    fi
    
    if [[ "$DESTROY_FILEVAULT_KEYS_ON_STANDBY" == "true" ]]; then
        sudo pmset -a destroyfvkeyonstandby 1 2>/dev/null
        echo "✅ FileVault key destruction on standby enabled"
    fi
    
    # Configure hibernation mode
    sudo pmset -a hibernatemode "$HIBERNATE_MODE" 2>/dev/null
    echo "✅ Hibernation mode set to $HIBERNATE_MODE"
    
    # Configure standby and autopoweroff
    sudo pmset -a standbydelay "$STANDBY_DELAY" 2>/dev/null
    
    if [[ "$AUTOPOWEROFF_ENABLED" == "true" ]]; then
        sudo pmset -a autopoweroff 1 2>/dev/null
        sudo pmset -a autopoweroffdelay "$AUTOPOWEROFF_DELAY" 2>/dev/null
        echo "✅ Auto power off enabled"
    fi
    
    log_action "Security power settings applied"
}

# Configure scheduled wake/sleep events
configure_scheduled_events() {
    echo "=== Configuring Scheduled Power Events ==="
    
    # Clear existing scheduled events
    sudo pmset repeat cancel 2>/dev/null
    
    if [[ "$SCHEDULED_WAKE_ENABLED" == "true" ]]; then
        # Schedule wake for business hours
        sudo pmset repeat wakeorpoweron "$BUSINESS_DAYS" "$BUSINESS_HOURS_START:00" 2>/dev/null
        echo "✅ Scheduled wake configured for business hours"
        log_action "Scheduled wake configured: $BUSINESS_DAYS at $BUSINESS_HOURS_START"
    fi
    
    if [[ "$SCHEDULED_SLEEP_ENABLED" == "true" ]]; then
        # Schedule sleep after business hours
        local sleep_time="${BUSINESS_HOURS_END}:30:00"
        sudo pmset repeat sleep "$BUSINESS_DAYS" "$sleep_time" 2>/dev/null
        echo "✅ Scheduled sleep configured for after hours"
        log_action "Scheduled sleep configured: $BUSINESS_DAYS at $sleep_time"
    fi
}

# Monitor power events and assertions
monitor_power_events() {
    echo "=== Starting Power Event Monitoring ==="
    
    local monitor_duration="${1:-3600}"  # Default 1 hour
    local end_time=$(($(date +%s) + monitor_duration))
    
    echo "Monitoring power events for $((monitor_duration/60)) minutes..."
    echo "Press Ctrl+C to stop monitoring"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # Check power assertions
        local assertion_count
        assertion_count=$(pmset -g assertions 2>/dev/null | grep -c "PreventUserIdleSystemSleep\|PreventUserIdleDisplaySleep" || echo 0)
        
        if [[ $assertion_count -gt 0 ]]; then
            echo "$(date '+%H:%M:%S') - Active power assertions: $assertion_count"
            pmset -g assertions 2>/dev/null | grep -E "(PreventUserIdleSystemSleep|PreventUserIdleDisplaySleep)" | head -3
        fi
        
        # Check thermal state
        local thermal_state
        thermal_state=$(pmset -g thermstate 2>/dev/null | grep -o "Normal\|Fair\|Serious\|Critical" | head -1)
        
        if [[ "$thermal_state" != "Normal" && -n "$thermal_state" ]]; then
            echo "$(date '+%H:%M:%S') - ⚠️  Thermal state: $thermal_state"
            log_action "Thermal warning: $thermal_state"
        fi
        
        # Check power source changes
        local current_power_source
        current_power_source=$(pmset -g ps 2>/dev/null | head -1)
        
        if [[ -f "/tmp/macfleet_last_power_source" ]]; then
            local last_power_source
            last_power_source=$(cat "/tmp/macfleet_last_power_source")
            
            if [[ "$current_power_source" != "$last_power_source" ]]; then
                echo "$(date '+%H:%M:%S') - 🔌 Power source changed: $current_power_source"
                log_action "Power source change: $current_power_source"
                audit_log "POWER_SOURCE_CHANGE" "DETECTED" "$current_power_source"
                
                # Auto-adjust power profile based on power source
                auto_adjust_power_profile
            fi
        fi
        
        echo "$current_power_source" > "/tmp/macfleet_last_power_source"
        
        sleep 30
    done
    
    echo "Power monitoring completed"
}

# Auto-adjust power profile based on conditions
auto_adjust_power_profile() {
    local current_hour
    current_hour=$(date +%H)
    
    local current_power_source
    current_power_source=$(pmset -g ps 2>/dev/null | head -1)
    
    echo "=== Auto-adjusting Power Profile ==="
    
    # Determine appropriate profile
    local new_profile=""
    
    if echo "$current_power_source" | grep -q "Battery Power"; then
        new_profile="energy_saver"
        echo "On battery power - switching to energy saver profile"
    elif [[ $current_hour -ge 18 || $current_hour -lt 9 ]]; then
        new_profile="$AFTER_HOURS_POWER_PROFILE"
        echo "After hours - switching to $new_profile profile"
    else
        new_profile="$POWER_PROFILE"
        echo "Business hours - switching to $new_profile profile"
    fi
    
    if [[ -n "$new_profile" ]]; then
        apply_power_profile "$new_profile"
        log_action "Auto-adjusted power profile to: $new_profile"
    fi
}

# Check power management compliance
check_power_compliance() {
    echo "=== Power Management Compliance Check ==="
    
    local compliance_issues=()
    local compliance_score=100
    
    # Check if power management is properly configured
    local current_settings
    current_settings=$(pmset -g 2>/dev/null)
    
    if [[ -z "$current_settings" ]]; then
        compliance_issues+=("Unable to read power management settings")
        compliance_score=$((compliance_score - 50))
    fi
    
    # Check sleep timers
    local system_sleep
    system_sleep=$(echo "$current_settings" | grep -E '^\s*sleep\s' | awk '{print $2}')
    
    if [[ "$system_sleep" == "0" ]] && [[ "$POWER_PROFILE" != "kiosk_mode" ]] && [[ "$POWER_PROFILE" != "presentation_mode" ]]; then
        compliance_issues+=("System sleep disabled (security risk)")
        compliance_score=$((compliance_score - 20))
    fi
    
    # Check display sleep
    local display_sleep
    display_sleep=$(echo "$current_settings" | grep -E '^\s*displaysleep\s' | awk '{print $2}')
    
    if [[ "$display_sleep" == "0" ]] && [[ "$POWER_PROFILE" != "kiosk_mode" ]] && [[ "$POWER_PROFILE" != "presentation_mode" ]]; then
        compliance_issues+=("Display sleep disabled (energy waste)")
        compliance_score=$((compliance_score - 15))
    fi
    
    # Check security settings
    local hibernatemode
    hibernatemode=$(echo "$current_settings" | grep -E '^\s*hibernatemode\s' | awk '{print $2}')
    
    if [[ "$hibernatemode" == "0" ]] && [[ "$DESTROY_FILEVAULT_KEYS_ON_STANDBY" == "true" ]]; then
        compliance_issues+=("Hibernation disabled but FileVault key destruction enabled")
        compliance_score=$((compliance_score - 10))
    fi
    
    # Check thermal management
    local thermal_state
    thermal_state=$(pmset -g thermstate 2>/dev/null | grep -o "Normal\|Fair\|Serious\|Critical" | head -1)
    
    if [[ "$thermal_state" == "Serious" || "$thermal_state" == "Critical" ]]; then
        compliance_issues+=("Thermal management issue: $thermal_state")
        compliance_score=$((compliance_score - 25))
    fi
    
    # Report compliance status
    echo "Compliance Score: $compliance_score/100"
    
    if [[ ${#compliance_issues[@]} -eq 0 ]]; then
        echo "✅ Power management configuration is compliant"
        audit_log "COMPLIANCE_CHECK" "PASSED" "Score: $compliance_score/100"
        return 0
    else
        echo "❌ Compliance issues found:"
        printf '  - %s\n' "${compliance_issues[@]}"
        audit_log "COMPLIANCE_CHECK" "FAILED" "Issues: ${#compliance_issues[@]} Score: $compliance_score/100"
        
        # Auto-remediation if enabled
        if [[ "$AUTO_APPLY_POLICIES" == "true" ]]; then
            echo "🔧 Auto-remediation enabled, applying correct power profile..."
            apply_power_profile "$POWER_PROFILE"
        fi
        
        return 1
    fi
}

# Generate power management report
generate_power_report() {
    local report_file="$POLICIES_DIR/power_report_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Generating Power Management Report ==="
    
    # Get current power information
    local power_source=""
    local battery_percentage=""
    local thermal_state=""
    local power_assertions=""
    
    if command -v pmset >/dev/null; then
        power_source=$(pmset -g ps 2>/dev/null | head -1 | sed 's/.*from //' | sed 's/;.*//')
        battery_percentage=$(pmset -g ps 2>/dev/null | grep -o '[0-9]*%' | head -1 | sed 's/%//')
        thermal_state=$(pmset -g thermstate 2>/dev/null | grep -o "Normal\|Fair\|Serious\|Critical" | head -1)
        power_assertions=$(pmset -g assertions 2>/dev/null | grep -c "PreventUserIdleSystemSleep\|PreventUserIdleDisplaySleep" || echo 0)
    fi
    
    # Get energy usage data
    local uptime_seconds
    uptime_seconds=$(uptime | awk '{print $3}' | cut -d',' -f1 | cut -d':' -f2)
    
    # Create JSON report
    cat > "$report_file" << EOF
{
  "report_type": "power_management",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "device_info": {
    "hostname": "$(hostname)",
    "os_version": "$(sw_vers -productVersion)",
    "serial_number": "$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)",
    "model": "$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F: '{print $2}' | xargs)"
  },
  "power_status": {
    "power_source": "$power_source",
    "battery_percentage": $([ -n "$battery_percentage" ] && echo "$battery_percentage" || echo "null"),
    "thermal_state": "${thermal_state:-Normal}",
    "active_power_assertions": $power_assertions
  },
  "power_settings": {
    "current_profile": "$POWER_PROFILE",
    "system_sleep_ac": "$SYSTEM_SLEEP_AC",
    "display_sleep_ac": "$DISPLAY_SLEEP_AC",
    "wake_on_lan": $WAKE_ON_LAN,
    "auto_restart_on_power_loss": $AUTOMATIC_RESTART_ON_POWER_LOSS
  },
  "energy_optimization": {
    "energy_optimization_enabled": $ENERGY_OPTIMIZATION,
    "reduce_brightness_battery": $REDUCE_BRIGHTNESS_BATTERY,
    "thermal_management": $THERMAL_MANAGEMENT
  },
  "compliance_status": {
    "policy_compliant": $(check_power_compliance >/dev/null 2>&1 && echo true || echo false),
    "auto_apply_policies": $AUTO_APPLY_POLICIES,
    "regulatory_compliance": "$REGULATORY_COMPLIANCE"
  },
  "sustainability": {
    "carbon_footprint_tracking": $CARBON_FOOTPRINT_TRACKING,
    "energy_star_compliant": $([ "$REGULATORY_COMPLIANCE" == "ENERGY_STAR" ] && echo true || echo false)
  }
}
EOF
    
    echo "Power management report saved to: $report_file"
    log_action "Power management report generated: $report_file"
}

# Prevent system sleep for critical operations
prevent_sleep_for_operation() {
    local operation_name="$1"
    local duration_seconds="$2"
    local prevent_display="${3:-false}"
    
    echo "=== Preventing Sleep for Operation: $operation_name ==="
    
    local caffeinate_options="-i"
    
    if [[ "$prevent_display" == "true" ]]; then
        caffeinate_options="$caffeinate_options -d"
    fi
    
    if [[ -n "$duration_seconds" ]]; then
        caffeinate_options="$caffeinate_options -t $duration_seconds"
    fi
    
    echo "Preventing system sleep for $operation_name..."
    log_action "Sleep prevention started for operation: $operation_name (duration: ${duration_seconds:-indefinite}s)"
    
    # Run caffeinate in background and return PID
    caffeinate $caffeinate_options &
    local caffeinate_pid=$!
    
    echo "Sleep prevention active (PID: $caffeinate_pid)"
    echo "$caffeinate_pid" > "/tmp/macfleet_caffeinate_$operation_name.pid"
    
    audit_log "SLEEP_PREVENTION" "STARTED" "Operation: $operation_name PID: $caffeinate_pid"
    
    return 0
}

# Stop sleep prevention for operation
stop_sleep_prevention() {
    local operation_name="$1"
    local pid_file="/tmp/macfleet_caffeinate_$operation_name.pid"
    
    if [[ -f "$pid_file" ]]; then
        local caffeinate_pid
        caffeinate_pid=$(cat "$pid_file")
        
        if kill -0 "$caffeinate_pid" 2>/dev/null; then
            kill "$caffeinate_pid"
            echo "Sleep prevention stopped for $operation_name (PID: $caffeinate_pid)"
            log_action "Sleep prevention stopped for operation: $operation_name"
            audit_log "SLEEP_PREVENTION" "STOPPED" "Operation: $operation_name PID: $caffeinate_pid"
        else
            echo "Sleep prevention process not found for $operation_name"
        fi
        
        rm -f "$pid_file"
    else
        echo "No active sleep prevention found for $operation_name"
    fi
}

# Main function with argument handling
main() {
    log_action "=== MacFleet Power Management Tool Started ==="
    
    case "${1:-status}" in
        "status")
            get_power_status
            ;;
        "profile")
            apply_power_profile "$2"
            ;;
        "monitor")
            monitor_power_events "$2"
            ;;
        "compliance")
            check_power_compliance
            ;;
        "report")
            generate_power_report
            ;;
        "prevent-sleep")
            prevent_sleep_for_operation "$2" "$3" "$4"
            ;;
        "allow-sleep")
            stop_sleep_prevention "$2"
            ;;
        "auto-adjust")
            auto_adjust_power_profile
            ;;
        "schedule")
            configure_scheduled_events
            ;;
        *)
            echo "MacFleet Enterprise Power Management Tool"
            echo "Usage: $0 [command] [options]"
            echo ""
            echo "Commands:"
            echo "  status                        - Show current power management status"
            echo "  profile [name]                - Apply specific power profile"
            echo "  monitor [duration]            - Monitor power events (duration in seconds)"
            echo "  compliance                    - Check power management compliance"
            echo "  report                        - Generate power management report"
            echo "  prevent-sleep [name] [duration] [display] - Prevent sleep for operation"
            echo "  allow-sleep [name]            - Stop sleep prevention for operation"
            echo "  auto-adjust                   - Auto-adjust power profile based on conditions"
            echo "  schedule                      - Configure scheduled power events"
            echo ""
            echo "Power Profiles:"
            echo "  corporate_standard            - Standard corporate power management (default)"
            echo "  energy_saver                  - Maximum energy efficiency"
            echo "  high_performance              - Performance-focused settings"
            echo "  security_focused              - Security-optimized power management"
            echo "  presentation_mode             - Prevent sleep during presentations"
            echo "  kiosk_mode                    - Always-on for kiosk devices"
            ;;
    esac
    
    log_action "=== Power management operation completed ==="
}

# Execute main function
main "$@"

## Advanced Power Management Features

### Business Hours Power Automation

```bash
#!/bin/bash

# Automated business hours power management
setup_business_hours_automation() {
    echo "=== Setting Up Business Hours Power Automation ==="
    
    # Create business hours power management script
    local automation_script="/Library/MacFleet/Scripts/business_hours_power.sh"
    mkdir -p "$(dirname "$automation_script")"
    
    cat > "$automation_script" << 'EOF'
#!/bin/bash

# Determine current time and apply appropriate power profile
current_hour=$(date +%H)
current_day=$(date +%u)  # 1=Monday, 7=Sunday

# Business hours: Monday-Friday 9AM-6PM
if [[ $current_day -le 5 ]] && [[ $current_hour -ge 9 ]] && [[ $current_hour -lt 18 ]]; then
    # Business hours
    /Library/MacFleet/Scripts/power_management.sh profile corporate_standard
elif [[ $current_day -gt 5 ]]; then
    # Weekend
    /Library/MacFleet/Scripts/power_management.sh profile energy_saver
else
    # After hours
    /Library/MacFleet/Scripts/power_management.sh profile security_focused
fi
EOF
    
    chmod +x "$automation_script"
    
    # Create launch daemon for automation
    local launch_daemon="/Library/LaunchDaemons/com.macfleet.power.automation.plist"
    
    cat > "$launch_daemon" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.power.automation</string>
    <key>ProgramArguments</key>
    <array>
        <string>$automation_script</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>9</integer>
            <key>Minute</key>
            <integer>0</integer>
        </dict>
        <dict>
            <key>Hour</key>
            <integer>18</integer>
            <key>Minute</key>
            <integer>0</integer>
        </dict>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF
    
    # Load the launch daemon
    sudo launchctl load "$launch_daemon" 2>/dev/null
    
    echo "✅ Business hours power automation configured"
    log_action "Business hours power automation setup completed"
}

# Battery optimization for laptops
optimize_battery_performance() {
    echo "=== Optimizing Battery Performance ==="
    
    # Check if device has a battery
    if ! system_profiler SPPowerDataType 2>/dev/null | grep -q "Battery Information"; then
        echo "No battery detected - skipping battery optimization"
        return 0
    fi
    
    # Get current battery information
    local battery_condition
    battery_condition=$(system_profiler SPPowerDataType | grep "Condition" | awk -F: '{print $2}' | xargs)
    
    local cycle_count
    cycle_count=$(system_profiler SPPowerDataType | grep "Cycle Count" | awk -F: '{print $2}' | xargs)
    
    echo "Battery Condition: $battery_condition"
    echo "Cycle Count: $cycle_count"
    
    # Apply battery-specific optimizations
    if [[ "$battery_condition" == "Replace Soon" || "$battery_condition" == "Replace Now" ]]; then
        echo "⚠️  Battery needs replacement - applying conservative settings"
        sudo pmset -b sleep 5 2>/dev/null
        sudo pmset -b displaysleep 2 2>/dev/null
        sudo pmset -b reducebright 1 2>/dev/null
        
        log_action "BATTERY WARNING: $battery_condition - Conservative settings applied"
        audit_log "BATTERY_WARNING" "DETECTED" "Condition: $battery_condition Cycles: $cycle_count"
    else
        echo "✅ Battery condition normal - applying standard optimization"
        sudo pmset -b sleep "$SYSTEM_SLEEP_BATTERY" 2>/dev/null
        sudo pmset -b displaysleep "$DISPLAY_SLEEP_BATTERY" 2>/dev/null
    fi
    
    # Enable optimized battery charging
    sudo pmset -a optimizedcharging 1 2>/dev/null
    
    echo "Battery optimization completed"
    log_action "Battery performance optimization applied"
}

# Thermal management
monitor_thermal_state() {
    echo "=== Thermal State Monitoring ==="
    
    local thermal_log="/var/log/macfleet_thermal.log"
    local monitoring_duration="${1:-300}"  # Default 5 minutes
    
    echo "Monitoring thermal state for $((monitoring_duration/60)) minutes..."
    
    local end_time=$(($(date +%s) + monitoring_duration))
    
    while [[ $(date +%s) -lt $end_time ]]; do
        local thermal_state
        thermal_state=$(pmset -g thermstate 2>/dev/null | grep -o "Normal\|Fair\|Serious\|Critical" | head -1)
        
        local cpu_temp=""
        if command -v powermetrics >/dev/null; then
            cpu_temp=$(sudo powermetrics -n 1 -s cpu_power 2>/dev/null | grep "CPU die temperature" | awk '{print $4}' | head -1)
        fi
        
        local timestamp
        timestamp=$(date '+%Y-%m-%d %H:%M:%S')
        
        echo "$timestamp - Thermal: $thermal_state CPU: ${cpu_temp:-N/A}°C" | tee -a "$thermal_log"
        
        case "$thermal_state" in
            "Serious"|"Critical")
                echo "🚨 THERMAL ALERT: $thermal_state - Taking protective action"
                # Reduce performance to cool down
                sudo pmset -a reducebright 1 2>/dev/null
                # Log critical thermal event
                log_action "THERMAL ALERT: $thermal_state detected - protective measures activated"
                audit_log "THERMAL_ALERT" "CRITICAL" "State: $thermal_state CPU: ${cpu_temp:-N/A}°C"
                ;;
            "Fair")
                echo "⚠️  Thermal warning: $thermal_state"
                log_action "Thermal warning: $thermal_state"
                ;;
        esac
        
        sleep 10
    done
    
    echo "Thermal monitoring completed"
}

## Important Configuration Notes

### macOS Power Management Architecture

- **Power Management Unit (PMU)** - Hardware-level power control
- **IOPMrootDomain** - Kernel power management
- **PowerManagement.framework** - User-space power APIs
- **pmset** - Command-line power management tool
- **Energy Saver** - System Preferences power interface

### Enterprise Integration Points

- **MDM Configuration Profiles** - Deploy power policies centrally
- **Energy Monitoring Systems** - Integration with facility management
- **Carbon Footprint Tracking** - Environmental compliance reporting
- **Business Intelligence** - Power usage analytics and optimization

### Best Practices for Enterprise Power Management

1. **Energy Efficiency Strategy**
   - Implement tiered power profiles based on usage patterns
   - Monitor and optimize energy consumption across the fleet
   - Align with corporate sustainability initiatives
   - Track cost savings from power management policies

2. **Security Considerations**
   - Enable FileVault key destruction on standby for sensitive data
   - Configure appropriate hibernation modes for security
   - Implement secure sleep modes for unattended devices
   - Balance security requirements with operational needs

3. **Performance Optimization**
   - Use high-performance profiles for resource-intensive tasks
   - Implement presentation modes for meeting scenarios
   - Configure thermal management for sustained workloads
   - Monitor battery health and optimize charging patterns

4. **Compliance and Reporting**
   - Generate energy usage reports for regulatory compliance
   - Track power management policy adherence
   - Document power optimization initiatives
   - Monitor environmental impact metrics

Remember to test power management configurations thoroughly in your environment before fleet-wide deployment to ensure they meet your organization's operational, security, and energy efficiency requirements. 

Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Configurando un Runner de GitHub Actions en un Mac Mini (Apple Silicon)

Runner de GitHub Actions

GitHub Actions es una plataforma poderosa de CI/CD que te permite automatizar tus flujos de trabajo de desarrollo de software. Aunque GitHub ofrece runners hospedados, los runners auto-hospedados proporcionan mayor control y personalización para tu configuración de CI/CD. Este tutorial te guía a través de la configuración y conexión de un runner auto-hospedado en un Mac mini para ejecutar pipelines de macOS.

Prerrequisitos

Antes de comenzar, asegúrate de tener:

  • Un Mac mini (regístrate en Macfleet)
  • Un repositorio de GitHub con derechos de administrador
  • Un gestor de paquetes instalado (preferiblemente Homebrew)
  • Git instalado en tu sistema

Paso 1: Crear una Cuenta de Usuario Dedicada

Primero, crea una cuenta de usuario dedicada para el runner de GitHub Actions:

# Crear la cuenta de usuario '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

# Establecer la contraseña para el usuario
sudo dscl . -passwd /Users/gh-runner tu_contraseña

# Agregar 'gh-runner' al grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Cambia a la nueva cuenta de usuario:

su gh-runner

Paso 2: Instalar Software Requerido

Instala Git y Rosetta 2 (si usas Apple Silicon):

# Instalar Git si no está ya instalado
brew install git

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

Paso 3: Configurar el Runner de GitHub Actions

  1. Ve a tu repositorio de GitHub
  2. Navega a Configuración > Actions > Runners

Runner de GitHub Actions

  1. Haz clic en "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecciona macOS como imagen del runner y ARM64 como arquitectura
  3. Sigue los comandos proporcionados para descargar y configurar el runner

Runner de GitHub Actions

Crea un archivo .env en el directorio _work del runner:

# archivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Ejecuta el script run.sh en tu directorio del runner para completar la configuración.
  2. Verifica que el runner esté activo y escuchando trabajos en la terminal y revisa la configuración del repositorio de GitHub para la asociación del runner y el estado Idle.

Runner de GitHub Actions

Paso 4: Configurar Sudoers (Opcional)

Si tus acciones requieren privilegios de root, configura el archivo sudoers:

sudo visudo

Agrega la siguiente línea:

gh-runner ALL=(ALL) NOPASSWD: ALL

Paso 5: Usar el Runner en Flujos de Trabajo

Configura tu flujo de trabajo de GitHub Actions para usar el runner auto-hospedado:

name: Flujo de trabajo de muestra

on:
  workflow_dispatch:

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

El runner está autenticado en tu repositorio y etiquetado con self-hosted, macOS, y ARM64. Úsalo en tus flujos de trabajo especificando estas etiquetas en el campo runs-on:

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

Mejores Prácticas

  • Mantén tu software del runner actualizado
  • Monitorea regularmente los logs del runner para problemas
  • Usa etiquetas específicas para diferentes tipos de runners
  • Implementa medidas de seguridad apropiadas
  • Considera usar múltiples runners para balanceo de carga

Solución de Problemas

Problemas comunes y soluciones:

  1. Runner no conectando:

    • Verifica conectividad de red
    • Verifica validez del token de GitHub
    • Asegúrate de permisos apropiados
  2. Fallas de construcción:

    • Verifica instalación de Xcode
    • Verifica dependencias requeridas
    • Revisa logs del flujo de trabajo
  3. Problemas de permisos:

    • Verifica permisos de usuario
    • Verifica configuración de sudoers
    • Revisa permisos del sistema de archivos

Conclusión

Ahora tienes un runner auto-hospedado de GitHub Actions configurado en tu Mac mini. Esta configuración te proporciona más control sobre tu entorno de CI/CD y te permite ejecutar flujos de trabajo específicos de macOS de manera eficiente.

Recuerda mantener regularmente tu runner y mantenerlo actualizado con los últimos parches de seguridad y versiones de software.

Aplicación Nativa

Aplicación nativa de Macfleet

Guía de Instalación de Macfleet

Macfleet es una solución poderosa de gestión de flota diseñada específicamente para entornos de Mac Mini alojados en la nube. Como proveedor de hosting en la nube de Mac Mini, puedes usar Macfleet para monitorear, gestionar y optimizar toda tu flota de instancias Mac virtualizadas.

Esta guía de instalación te llevará a través de la configuración del monitoreo de Macfleet en sistemas macOS, Windows y Linux para asegurar una supervisión integral de tu infraestructura en la nube.

🍎 macOS

  • Descarga el archivo .dmg para Mac aquí
  • Haz doble clic en el archivo .dmg descargado
  • Arrastra la aplicación Macfleet a la carpeta Aplicaciones
  • Expulsa el archivo .dmg
  • Abre Preferencias del Sistema > Seguridad y Privacidad
    • Pestaña Privacidad > Accesibilidad
    • Marca Macfleet para permitir el monitoreo
  • Inicia Macfleet desde Aplicaciones
  • El seguimiento comienza automáticamente

🪟 Windows

  • Descarga el archivo .exe para Windows aquí
  • Haz clic derecho en el archivo .exe > "Ejecutar como administrador"
  • Sigue el asistente de instalación
  • Acepta los términos y condiciones
  • Permite en Windows Defender si se solicita
  • Concede permisos de monitoreo de aplicaciones
  • Inicia Macfleet desde el Menú Inicio
  • La aplicación comienza el seguimiento automáticamente

🐧 Linux

  • Descarga el paquete .deb (Ubuntu/Debian) o .rpm (CentOS/RHEL) aquí
  • Instala usando tu gestor de paquetes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permite permisos de acceso X11 si se solicita
  • Agrega el usuario a los grupos apropiados si es necesario
  • Inicia Macfleet desde el menú de Aplicaciones
  • La aplicación comienza el seguimiento automáticamente

Nota: Después de la instalación en todos los sistemas, inicia sesión con tus credenciales de Macfleet para sincronizar datos con tu panel de control.