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.

Deploy ZIP Files to Macs Using URLs

Deploying applications and files across your MacFleet can be streamlined by hosting ZIP files on a server and automatically downloading them to target devices. This tutorial shows how to create robust scripts for ZIP file deployment using URLs.

Understanding the Process

The deployment process involves:

  1. Download - Fetch the ZIP file from a URL using curl
  2. Extract - Unzip the contents using unzip
  3. Install - Optionally install or move files to their final location
  4. Cleanup - Remove temporary files

Basic ZIP Deployment Script

Simple Download and Extract

#!/bin/bash

# Basic ZIP deployment script
cd /tmp

# Download the ZIP file
curl -k https://example.com/myapp.zip -o "myapp.zip"

# Extract the contents
unzip "myapp.zip"

Enhanced Enterprise Script

For production environments with error handling and logging:

#!/bin/bash

# ZIP File Deployment Script for MacFleet
# Compatible with macOS 10.14+

# Configuration variables
DOWNLOAD_URL="$1"  # First argument: URL to ZIP file
ZIP_NAME="$2"      # Second argument: ZIP filename
DESTINATION="${3:-/tmp}"  # Third argument: destination (default: /tmp)
LOG_FILE="/var/log/zip_deployment.log"

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Function to validate URL
validate_url() {
    local url="$1"
    if [[ ! "$url" =~ ^https?:// ]]; then
        log_message "✗ Invalid URL format: $url"
        return 1
    fi
    return 0
}

# Function to check internet connectivity
check_connectivity() {
    if ! ping -c 1 google.com &> /dev/null; then
        log_message "✗ No internet connectivity"
        return 1
    fi
    return 0
}

# Function to download ZIP file
download_zip() {
    local url="$1"
    local filename="$2"
    local destination="$3"
    
    log_message "Starting download from: $url"
    
    # Create destination directory if it doesn't exist
    mkdir -p "$destination"
    cd "$destination" || return 1
    
    # Download with progress and error handling
    if curl -L --fail --connect-timeout 30 --max-time 300 \
            --progress-bar "$url" -o "$filename"; then
        log_message "✓ Download completed: $filename"
        return 0
    else
        log_message "✗ Download failed from: $url"
        return 1
    fi
}

# Function to extract ZIP file
extract_zip() {
    local filename="$1"
    local destination="$2"
    
    cd "$destination" || return 1
    
    # Check if ZIP file exists
    if [[ ! -f "$filename" ]]; then
        log_message "✗ ZIP file not found: $filename"
        return 1
    fi
    
    # Test ZIP integrity
    if ! unzip -t "$filename" &> /dev/null; then
        log_message "✗ ZIP file is corrupted: $filename"
        return 1
    fi
    
    # Extract files
    if unzip -o "$filename"; then
        log_message "✓ Extraction completed: $filename"
        return 0
    else
        log_message "✗ Extraction failed: $filename"
        return 1
    fi
}

# Function to install application (if .app bundle found)
install_application() {
    local source_dir="$1"
    
    # Look for .app bundles
    local app_bundle
    app_bundle=$(find "$source_dir" -name "*.app" -type d | head -1)
    
    if [[ -n "$app_bundle" ]]; then
        local app_name
        app_name=$(basename "$app_bundle")
        
        log_message "Found application bundle: $app_name"
        
        # Copy to Applications folder
        if cp -R "$app_bundle" "/Applications/"; then
            log_message "✓ Application installed: $app_name"
            return 0
        else
            log_message "✗ Application installation failed: $app_name"
            return 1
        fi
    else
        log_message "! No application bundle found for installation"
        return 0
    fi
}

# Function to cleanup temporary files
cleanup() {
    local destination="$1"
    local filename="$2"
    
    cd "$destination" || return 1
    
    if [[ -f "$filename" ]]; then
        rm -f "$filename"
        log_message "✓ Cleanup completed: $filename"
    fi
}

# Main deployment function
deploy_zip() {
    log_message "=== Starting ZIP deployment ==="
    
    # Validate inputs
    if [[ -z "$DOWNLOAD_URL" ]] || [[ -z "$ZIP_NAME" ]]; then
        log_message "✗ Usage: $0 <download_url> <zip_filename> [destination]"
        return 1
    fi
    
    # Validate URL format
    if ! validate_url "$DOWNLOAD_URL"; then
        return 1
    fi
    
    # Check connectivity
    if ! check_connectivity; then
        return 1
    fi
    
    # Download ZIP file
    if ! download_zip "$DOWNLOAD_URL" "$ZIP_NAME" "$DESTINATION"; then
        return 1
    fi
    
    # Extract ZIP file
    if ! extract_zip "$ZIP_NAME" "$DESTINATION"; then
        return 1
    fi
    
    # Attempt application installation
    install_application "$DESTINATION"
    
    # Cleanup temporary ZIP file
    cleanup "$DESTINATION" "$ZIP_NAME"
    
    log_message "=== ZIP deployment completed successfully ==="
    return 0
}

# Execute main function
if deploy_zip; then
    exit 0
else
    log_message "=== ZIP deployment failed ==="
    exit 1
fi

Quick Deployment Scripts

Download to Applications

#!/bin/bash

# Download and install app directly to Applications
URL="https://example.com/MyApp.zip"
ZIP_NAME="MyApp.zip"

cd /tmp
curl -L "$URL" -o "$ZIP_NAME"
unzip "$ZIP_NAME"

# Find and move .app bundle
APP_BUNDLE=$(find . -name "*.app" -type d | head -1)
if [[ -n "$APP_BUNDLE" ]]; then
    cp -R "$APP_BUNDLE" /Applications/
    echo "Application installed successfully"
fi

# Cleanup
rm -f "$ZIP_NAME"
rm -rf "${ZIP_NAME%.zip}"

Download with Checksum Verification

#!/bin/bash

URL="https://example.com/myapp.zip"
ZIP_NAME="myapp.zip"
EXPECTED_SHA256="abc123..."  # Replace with actual checksum

cd /tmp
curl -L "$URL" -o "$ZIP_NAME"

# Verify checksum
if echo "$EXPECTED_SHA256  $ZIP_NAME" | shasum -a 256 -c; then
    echo "Checksum verified"
    unzip "$ZIP_NAME"
else
    echo "Checksum verification failed"
    exit 1
fi

Usage Examples

Command Line Usage

# Basic usage
./deploy_zip.sh "https://example.com/app.zip" "app.zip"

# Custom destination
./deploy_zip.sh "https://example.com/app.zip" "app.zip" "/Applications"

# With logging
./deploy_zip.sh "https://example.com/app.zip" "app.zip" 2>&1 | tee deployment.log

MacFleet Deployment

#!/bin/bash

# Deploy multiple applications
APPS=(
    "https://cdn.example.com/productivity.zip:productivity.zip"
    "https://cdn.example.com/security.zip:security.zip"
    "https://cdn.example.com/utilities.zip:utilities.zip"
)

for app in "${APPS[@]}"; do
    IFS=':' read -r url filename <<< "$app"
    echo "Deploying: $filename"
    ./deploy_zip.sh "$url" "$filename"
done

Troubleshooting

IssueSolution
Download failsCheck URL accessibility and internet connection
ZIP extraction errorsVerify ZIP file integrity with unzip -t
Permission deniedRun script with admin privileges
App not installingCheck for .app bundle in extracted contents
Slow downloadsIncrease curl timeout values

Security Considerations

  • HTTPS URLs - Always use secure connections when possible
  • Checksum verification - Verify file integrity before extraction
  • Code signing - Verify application signatures before installation
  • Sandboxed downloads - Use /tmp for temporary storage

File Location Reference

  • Temporary files: /tmp/
  • Applications: /Applications/
  • User applications: ~/Applications/
  • System utilities: /usr/local/bin/
  • Logs: /var/log/zip_deployment.log

Advanced Features

Progress Monitoring

# Show download progress
curl --progress-bar -L "$URL" -o "$ZIP_NAME"

# Or with detailed progress
curl -# -L "$URL" -o "$ZIP_NAME"

Retry Logic

# Retry download up to 3 times
for i in {1..3}; do
    if curl -L "$URL" -o "$ZIP_NAME"; then
        break
    elif [[ $i -eq 3 ]]; then
        echo "Download failed after 3 attempts"
        exit 1
    fi
    sleep 5
done

Important Notes

  • ZIP files are temporarily stored in /tmp by default
  • Use secure HTTPS URLs when possible
  • Test scripts on a small group before enterprise deployment
  • Monitor disk space when deploying large files
  • Consider bandwidth limitations in your network

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.