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.

Package Management with Homebrew on macOS

Streamline software deployment and package management across your MacFleet devices using Homebrew. This tutorial covers enterprise software installation, configuration management, compliance tracking, and automated deployment workflows for comprehensive fleet management.

Understanding Homebrew for Enterprise

Homebrew provides powerful package management for macOS:

  • Formula packages - Command-line tools and libraries
  • Cask applications - GUI applications and large binaries
  • Tap repositories - Third-party package sources
  • Bundle files - Declarative package manifests
  • Services - Background daemon management

Basic Homebrew Installation

Install Homebrew

#!/bin/bash

# Install Homebrew package manager
install_homebrew() {
    echo "=== Installing Homebrew Package Manager ==="
    
    # Check if Homebrew is already installed
    if command -v brew >/dev/null 2>&1; then
        echo "✅ Homebrew already installed: $(brew --version | head -1)"
        return 0
    fi
    
    echo "📦 Installing Homebrew..."
    
    # Install Homebrew
    if /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
        echo "✅ Homebrew installation completed"
        
        # Add Homebrew to PATH for current session
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
        
        # Verify installation
        if command -v brew >/dev/null 2>&1; then
            echo "🔍 Homebrew version: $(brew --version | head -1)"
            return 0
        else
            echo "❌ Homebrew installation verification failed"
            return 1
        fi
    else
        echo "❌ Homebrew installation failed"
        return 1
    fi
}

# Execute installation
install_homebrew

Enhanced Package Installation Script

#!/bin/bash

# Enhanced package installation based on GitHub Gist
# Reference: https://gist.github.com/CliffordAnderson/817777b5dc0e67769e4b

enhanced_package_installation() {
    echo "=== Enhanced Package Installation ==="
    
    # Ensure Homebrew is installed
    if ! command -v brew >/dev/null 2>&1; then
        echo "❌ Homebrew not found. Installing..."
        install_homebrew || return 1
    fi
    
    # Update Homebrew
    echo "🔄 Updating Homebrew..."
    brew update
    
    # Programming Languages
    echo "💻 Installing programming languages..."
    brew install scala
    brew install --cask r
    brew install openjdk
    
    # Development Tools
    echo "🛠️ Installing development tools..."
    brew install docker
    brew install git
    brew install --cask github
    brew install --cask visual-studio-code
    brew install --cask hyper
    
    # Communication Apps
    echo "💬 Installing communication apps..."
    brew install --cask discord
    brew install --cask microsoft-teams
    brew install --cask slack
    brew install --cask zoom
    
    # Web Tools
    echo "🌐 Installing web tools..."
    brew install httpie
    brew install node
    brew install nvm
    brew install --cask firefox
    brew install --cask google-chrome
    brew install --cask postman
    
    # File Storage
    echo "📁 Installing file storage tools..."
    brew install --cask dropbox
    brew install --cask onedrive
    
    # Writing Apps
    echo "✍️ Installing writing apps..."
    brew install pandoc
    brew install --cask zotero
    brew install --cask microsoft-word
    
    # Other Applications
    echo "🎯 Installing additional applications..."
    brew install --cask anki
    
    echo "✅ Package installation completed"
}

# Execute enhanced installation
enhanced_package_installation

Enterprise Homebrew Management System

#!/bin/bash

# MacFleet Enterprise Homebrew Management System
# Comprehensive package deployment, compliance tracking, and fleet management

# Configuration
LOG_FILE="/var/log/macfleet_homebrew.log"
CONFIG_DIR="/etc/macfleet/packages"
PROFILES_DIR="$CONFIG_DIR/profiles"
CACHE_DIR="/var/cache/macfleet/homebrew"
REPORTS_DIR="$CONFIG_DIR/reports"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"

# Package profiles for different roles
declare -A PACKAGE_PROFILES=(
    ["developer"]="git,node,python,docker,visual-studio-code,github,postman,hyper"
    ["designer"]="adobe-creative-cloud,figma,sketch,canva,affinity-designer,imageoptim"
    ["manager"]="microsoft-office,slack,zoom,teams,dropbox,onedrive,notion"
    ["analyst"]="r,python,tableau,microsoft-excel,jupyter-notebook,pandas"
    ["security"]="wireshark,nmap,burp-suite,malwarebytes,1password,gpg-suite"
    ["education"]="zoom,microsoft-office,rstudio,zotero,anki,mendeley"
    ["minimal"]="google-chrome,firefox,zoom,slack"
    ["corporate"]="microsoft-office,teams,onedrive,1password,chrome-enterprise"
)

# Compliance frameworks
declare -A COMPLIANCE_PACKAGES=(
    ["hipaa"]="1password,malwarebytes,gpg-suite,microsoft-office"
    ["sox"]="microsoft-office,1password,box-drive,tableau"
    ["gdpr"]="1password,gpg-suite,notion,signal"
    ["iso27001"]="1password,malwarebytes,gpg-suite,microsoft-defender"
)

# License tracking
declare -A LICENSE_REQUIRED=(
    ["microsoft-office"]="commercial"
    ["adobe-creative-cloud"]="commercial"
    ["tableau"]="commercial"
    ["sketch"]="commercial"
    ["1password"]="commercial"
    ["zoom"]="freemium"
    ["slack"]="freemium"
    ["notion"]="freemium"
)

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

# Setup directories
setup_directories() {
    for dir in "$CONFIG_DIR" "$PROFILES_DIR" "$CACHE_DIR" "$REPORTS_DIR" "$COMPLIANCE_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Created directory: $dir"
        fi
    done
}

# Ensure Homebrew is installed and configured
ensure_homebrew() {
    log_action "Ensuring Homebrew is properly configured"
    
    # Check if Homebrew is installed
    if ! command -v brew >/dev/null 2>&1; then
        log_action "Installing Homebrew..."
        if ! /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
            log_action "❌ Failed to install Homebrew"
            return 1
        fi
        
        # Configure PATH
        if [[ -f "/opt/homebrew/bin/brew" ]]; then
            eval "$(/opt/homebrew/bin/brew shellenv)"
        elif [[ -f "/usr/local/bin/brew" ]]; then
            eval "$(/usr/local/bin/brew shellenv)"
        fi
    fi
    
    # Update Homebrew
    log_action "Updating Homebrew..."
    brew update 2>/dev/null || log_action "⚠️ Homebrew update failed"
    
    # Verify Homebrew health
    if brew doctor >/dev/null 2>&1; then
        log_action "✅ Homebrew health check passed"
    else
        log_action "⚠️ Homebrew health check issues detected"
    fi
    
    return 0
}

# Install packages from profile
install_package_profile() {
    local profile_name="$1"
    local dry_run="${2:-false}"
    
    log_action "Installing package profile: $profile_name (dry_run: $dry_run)"
    
    # Get profile packages
    local profile_packages="${PACKAGE_PROFILES[$profile_name]}"
    if [[ -z "$profile_packages" ]]; then
        log_action "❌ Unknown profile: $profile_name"
        return 1
    fi
    
    # Ensure Homebrew is ready
    ensure_homebrew || return 1
    
    # Parse packages
    IFS=',' read -ra PACKAGES <<< "$profile_packages"
    
    local success_count=0
    local failure_count=0
    local already_installed=0
    
    for package in "${PACKAGES[@]}"; do
        # Clean package name
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        log_action "Processing package: $package"
        
        if [[ "$dry_run" == "true" ]]; then
            echo "Would install: $package"
            continue
        fi
        
        # Check if already installed
        if is_package_installed "$package"; then
            log_action "✅ Package already installed: $package"
            already_installed=$((already_installed + 1))
            continue
        fi
        
        # Install package
        if install_single_package "$package"; then
            log_action "✅ Successfully installed: $package"
            success_count=$((success_count + 1))
        else
            log_action "❌ Failed to install: $package"
            failure_count=$((failure_count + 1))
        fi
    done
    
    # Summary
    log_action "Installation summary - Success: $success_count, Failed: $failure_count, Already installed: $already_installed"
    
    # Generate installation report
    generate_installation_report "$profile_name" "$success_count" "$failure_count" "$already_installed"
    
    return 0
}

# Check if package is installed
is_package_installed() {
    local package="$1"
    
    # Check if it's a cask
    if brew list --cask "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    # Check if it's a formula
    if brew list "$package" >/dev/null 2>&1; then
        return 0
    fi
    
    return 1
}

# Install single package
install_single_package() {
    local package="$1"
    
    # Try as cask first (for GUI applications)
    if brew install --cask "$package" 2>/dev/null; then
        return 0
    fi
    
    # Try as formula (for CLI tools)
    if brew install "$package" 2>/dev/null; then
        return 0
    fi
    
    return 1
}

# Generate comprehensive software inventory
generate_software_inventory() {
    log_action "Generating comprehensive software inventory"
    
    local inventory_file="$REPORTS_DIR/software_inventory_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$inventory_file" << EOF
{
    "inventory_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "homebrew_version": "$(brew --version | head -1)",
        "generator": "MacFleet Homebrew Manager"
    },
    "installed_packages": {
        "formulae": $(brew list --formula --json),
        "casks": $(brew list --cask --json)
    },
    "package_summary": {
        "total_formulae": $(brew list --formula | wc -l | tr -d ' '),
        "total_casks": $(brew list --cask | wc -l | tr -d ' '),
        "outdated_packages": $(brew outdated --json)
    },
    "system_info": {
        "homebrew_prefix": "$(brew --prefix)",
        "homebrew_cellar": "$(brew --cellar)",
        "homebrew_cache": "$(brew --cache)"
    }
}
EOF

    log_action "✅ Software inventory generated: $inventory_file"
    echo "$inventory_file"
}

# License compliance check
check_license_compliance() {
    log_action "Checking license compliance for installed packages"
    
    local compliance_report="$COMPLIANCE_DIR/license_compliance_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "check_type": "license_compliance"
    },
    "license_analysis": [
EOF

    local first=true
    local compliance_issues=0
    
    # Check installed casks for license requirements
    while IFS= read -r package; do
        local license_type="${LICENSE_REQUIRED[$package]}"
        
        if [[ -n "$license_type" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$compliance_report"
            fi
            
            local compliance_status="unknown"
            local needs_attention=false
            
            case "$license_type" in
                "commercial")
                    compliance_status="requires_license"
                    needs_attention=true
                    compliance_issues=$((compliance_issues + 1))
                    ;;
                "freemium")
                    compliance_status="freemium_check_usage"
                    ;;
            esac
            
            cat >> "$compliance_report" << EOF
        {
            "package": "$package",
            "license_type": "$license_type",
            "compliance_status": "$compliance_status",
            "needs_attention": $needs_attention,
            "installed_date": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')"
        }
EOF
        fi
    done < <(brew list --cask)
    
    cat >> "$compliance_report" << EOF
    ],
    "summary": {
        "total_packages_checked": $(brew list --cask | wc -l | tr -d ' '),
        "license_issues_found": $compliance_issues,
        "compliance_status": "$([ $compliance_issues -eq 0 ] && echo 'compliant' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ License compliance check completed: $compliance_report"
    echo "$compliance_report"
}

# Update all packages
update_all_packages() {
    local update_mode="${1:-safe}"  # safe, aggressive, or security-only
    
    log_action "Starting package updates (mode: $update_mode)"
    
    # Ensure Homebrew is ready
    ensure_homebrew || return 1
    
    # Update Homebrew itself
    log_action "Updating Homebrew..."
    if brew update; then
        log_action "✅ Homebrew updated successfully"
    else
        log_action "❌ Homebrew update failed"
        return 1
    fi
    
    # Get outdated packages
    local outdated_formulae outdated_casks
    outdated_formulae=$(brew outdated --formula --quiet)
    outdated_casks=$(brew outdated --cask --quiet)
    
    case "$update_mode" in
        "safe")
            # Update formulae only (CLI tools are generally safer to update)
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Updating outdated formulae: $outdated_formulae"
                brew upgrade
            fi
            ;;
        "aggressive")
            # Update everything
            if [[ -n "$outdated_formulae" ]]; then
                log_action "Updating all outdated formulae"
                brew upgrade
            fi
            if [[ -n "$outdated_casks" ]]; then
                log_action "Updating all outdated casks"
                brew upgrade --cask
            fi
            ;;
        "security-only")
            # Only update packages with known security issues
            # This would require integration with vulnerability databases
            log_action "Security-only updates not yet implemented"
            ;;
    esac
    
    # Cleanup
    log_action "Cleaning up old versions..."
    brew cleanup
    
    log_action "✅ Package updates completed"
    
    # Generate post-update inventory
    generate_software_inventory
}

# Generate Brewfile for current installation
generate_brewfile() {
    local brewfile_path="${1:-$CONFIG_DIR/Brewfile}"
    
    log_action "Generating Brewfile: $brewfile_path"
    
    # Create Brewfile header
    cat > "$brewfile_path" << EOF
# MacFleet Brewfile
# Generated on $(date)
# Hostname: $(hostname)

# Taps
EOF

    # Add taps
    brew tap | while read -r tap; do
        echo "tap \"$tap\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Formulae" >> "$brewfile_path"
    
    # Add formulae
    brew list --formula | while read -r formula; do
        echo "brew \"$formula\"" >> "$brewfile_path"
    done
    
    echo "" >> "$brewfile_path"
    echo "# Casks" >> "$brewfile_path"
    
    # Add casks
    brew list --cask | while read -r cask; do
        echo "cask \"$cask\"" >> "$brewfile_path"
    done
    
    log_action "✅ Brewfile generated: $brewfile_path"
    echo "$brewfile_path"
}

# Install from Brewfile
install_from_brewfile() {
    local brewfile_path="$1"
    local dry_run="${2:-false}"
    
    if [[ ! -f "$brewfile_path" ]]; then
        log_action "❌ Brewfile not found: $brewfile_path"
        return 1
    fi
    
    log_action "Installing from Brewfile: $brewfile_path (dry_run: $dry_run)"
    
    # Ensure Homebrew is ready
    ensure_homebrew || return 1
    
    if [[ "$dry_run" == "true" ]]; then
        log_action "Dry run - would install packages from: $brewfile_path"
        brew bundle --file="$brewfile_path" --verbose --no-install
    else
        # Install packages from Brewfile
        if brew bundle --file="$brewfile_path"; then
            log_action "✅ Brewfile installation completed"
            return 0
        else
            log_action "❌ Brewfile installation failed"
            return 1
        fi
    fi
}

# Security audit of installed packages
security_audit() {
    log_action "Performing security audit of installed packages"
    
    local audit_report="$REPORTS_DIR/security_audit_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$audit_report" << EOF
{
    "audit_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "audit_type": "security"
    },
    "security_findings": [
EOF

    local first=true
    local security_issues=0
    
    # Check for known vulnerable packages (simplified check)
    # In production, this would integrate with CVE databases
    local vulnerable_packages=("python@3.8" "node@14" "openssl@1.1")
    
    for vuln_package in "${vulnerable_packages[@]}"; do
        if is_package_installed "$vuln_package"; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$audit_report"
            fi
            
            cat >> "$audit_report" << EOF
        {
            "package": "$vuln_package",
            "severity": "medium",
            "issue": "potentially_outdated_version",
            "recommendation": "update_to_latest_version",
            "installed_version": "$(brew list --versions "$vuln_package" | awk '{print $2}')"
        }
EOF
            security_issues=$((security_issues + 1))
        fi
    done
    
    cat >> "$audit_report" << EOF
    ],
    "summary": {
        "total_packages_audited": $(( $(brew list --formula | wc -l) + $(brew list --cask | wc -l) )),
        "security_issues_found": $security_issues,
        "security_status": "$([ $security_issues -eq 0 ] && echo 'secure' || echo 'requires_attention')"
    }
}
EOF

    log_action "✅ Security audit completed: $audit_report"
    echo "$audit_report"
}

# Generate installation report
generate_installation_report() {
    local profile_name="$1"
    local success_count="$2"
    local failure_count="$3"
    local already_installed="$4"
    
    local report_file="$REPORTS_DIR/installation_report_${profile_name}_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$report_file" << EOF
{
    "installation_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "profile": "$profile_name",
        "generator": "MacFleet Homebrew Manager"
    },
    "installation_results": {
        "successful_installations": $success_count,
        "failed_installations": $failure_count,
        "already_installed": $already_installed,
        "total_processed": $(( success_count + failure_count + already_installed ))
    },
    "post_installation_inventory": $(generate_software_inventory | tail -n +2 | head -n -1)
}
EOF

    log_action "✅ Installation report generated: $report_file"
    echo "$report_file"
}

# Main execution function
main() {
    local action="${1:-inventory}"
    local parameter="$2"
    local additional_param="$3"
    
    log_action "=== MacFleet Homebrew Management Started ==="
    log_action "Action: $action"
    log_action "Parameter: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "install-profile")
            if [[ -z "$parameter" ]]; then
                echo "Available package profiles:"
                for profile in "${!PACKAGE_PROFILES[@]}"; do
                    echo "  - $profile: ${PACKAGE_PROFILES[$profile]}"
                done
                echo ""
                echo "Usage: $0 install-profile <profile_name> [dry_run]"
                exit 1
            fi
            install_package_profile "$parameter" "$additional_param"
            ;;
        "inventory")
            generate_software_inventory
            ;;
        "update")
            update_all_packages "$parameter"
            ;;
        "compliance")
            check_license_compliance
            ;;
        "security")
            security_audit
            ;;
        "brewfile-generate")
            generate_brewfile "$parameter"
            ;;
        "brewfile-install")
            if [[ -z "$parameter" ]]; then
                echo "Usage: $0 brewfile-install <brewfile_path> [dry_run]"
                exit 1
            fi
            install_from_brewfile "$parameter" "$additional_param"
            ;;
        "ensure")
            ensure_homebrew
            ;;
        *)
            echo "Usage: $0 {install-profile|inventory|update|compliance|security|brewfile-generate|brewfile-install|ensure}"
            echo "  install-profile    - Install packages from predefined profile"
            echo "  inventory         - Generate software inventory report"
            echo "  update           - Update all packages (safe|aggressive|security-only)"
            echo "  compliance       - Check license compliance"
            echo "  security         - Perform security audit"
            echo "  brewfile-generate - Generate Brewfile from current installation"
            echo "  brewfile-install  - Install packages from Brewfile"
            echo "  ensure           - Ensure Homebrew is installed and configured"
            exit 1
            ;;
    esac
    
    log_action "=== Homebrew management completed ==="
}

# Execute main function
main "$@"

Advanced Package Management Features

Custom Package Profile Creation

#!/bin/bash

# Create custom package profile
create_custom_profile() {
    local profile_name="$1"
    local packages="$2"
    
    echo "=== Creating Custom Package Profile ==="
    echo "Profile: $profile_name"
    echo "Packages: $packages"
    
    # Validate packages exist
    IFS=',' read -ra PACKAGE_LIST <<< "$packages"
    local valid_packages=()
    
    for package in "${PACKAGE_LIST[@]}"; do
        package=$(echo "$package" | sed 's/^[ \t]*//;s/[ \t]*$//')
        
        # Check if package exists in Homebrew
        if brew search --formula --cask "$package" | grep -q "^$package$"; then
            valid_packages+=("$package")
            echo "✅ Valid package: $package"
        else
            echo "⚠️  Package not found: $package"
        fi
    done
    
    if [[ ${#valid_packages[@]} -eq 0 ]]; then
        echo "❌ No valid packages found"
        return 1
    fi
    
    # Create profile
    local profile_packages
    printf -v profile_packages '%s,' "${valid_packages[@]}"
    profile_packages=${profile_packages%,}  # Remove trailing comma
    
    PACKAGE_PROFILES["$profile_name"]="$profile_packages"
    
    echo "✅ Custom profile created: $profile_name"
    echo "Packages: $profile_packages"
}

Automated License Management

#!/bin/bash

# Automated license management and tracking
manage_software_licenses() {
    echo "=== Software License Management ==="
    
    local license_db="$COMPLIANCE_DIR/license_database.json"
    
    # Create license database if it doesn't exist
    if [[ ! -f "$license_db" ]]; then
        cat > "$license_db" << EOF
{
    "license_metadata": {
        "created": "$(date -Iseconds)",
        "last_updated": "$(date -Iseconds)"
    },
    "licenses": {},
    "compliance_rules": {}
}
EOF
    fi
    
    # Scan for commercial software
    local commercial_software=()
    while IFS= read -r package; do
        if [[ -n "${LICENSE_REQUIRED[$package]}" ]]; then
            commercial_software+=("$package")
        fi
    done < <(brew list --cask)
    
    echo "Found ${#commercial_software[@]} packages requiring license management:"
    printf '%s\n' "${commercial_software[@]}"
    
    # Generate license report
    local license_report="$REPORTS_DIR/license_report_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$license_report" << EOF
{
    "license_report_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)"
    },
    "commercial_software": [
EOF

    local first=true
    for package in "${commercial_software[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$license_report"
        fi
        
        cat >> "$license_report" << EOF
        {
            "package": "$package",
            "license_type": "${LICENSE_REQUIRED[$package]}",
            "installed_version": "$(brew list --cask --versions "$package" 2>/dev/null | awk '{print $2}' || echo 'unknown')",
            "license_status": "requires_verification"
        }
EOF
    done
    
    cat >> "$license_report" << EOF
    ]
}
EOF

    echo "📋 License report generated: $license_report"
}

Best Practices

🚀 Enterprise Deployment

  • Profile-based installations for different user roles and departments
  • Centralized package management with Brewfile deployment across fleets
  • Automated software inventory tracking and reporting
  • License compliance monitoring with automated auditing

🔐 Security Management

  • Regular security audits of installed packages and dependencies
  • Vulnerability scanning integration with CVE databases
  • Package signature verification and trusted source validation
  • Controlled update deployment with testing phases

📋 Compliance and Governance

  • License tracking for commercial software compliance
  • Policy enforcement based on organizational requirements
  • Audit trails for all package installations and updates
  • Cost management through license optimization

🔧 Maintenance and Optimization

  • Automated updates with rollback capabilities
  • Cleanup and optimization to manage disk space
  • Performance monitoring of package management operations
  • Custom profile creation for specialized use cases

Important Notes

  • Test deployments in staging environments before production rollout
  • Backup configurations before major package updates
  • Monitor license compliance to avoid legal and financial risks
  • Regular inventory audits to maintain accurate software tracking
  • Network bandwidth considerations for large-scale deployments
  • User communication for software changes and updates

Integration with Enterprise Systems

The Homebrew management system can be integrated with:

  • MDM solutions for policy enforcement
  • Asset management systems for inventory tracking
  • License management platforms for compliance automation
  • Security tools for vulnerability assessment
  • Monitoring systems for deployment tracking

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.