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.

Disk Image Management on macOS

Create and manage disk images on your MacFleet devices for efficient data packaging, software distribution, and system deployment. This tutorial covers disk image creation from folders, advanced formatting options, encryption, compression, and enterprise-scale image management workflows.

Understanding Disk Images

Disk images are file containers that replicate the exact structure and content of storage volumes, providing powerful capabilities for enterprise deployment:

Benefits of Disk Images

  • Software Distribution - Package applications and configurations for deployment
  • Data Backup - Create portable snapshots of folder contents
  • System Deployment - Standardize configurations across multiple devices
  • Secure Transport - Encrypted images for sensitive data transfer
  • Version Control - Maintain different versions of software packages
  • Network Efficiency - Compressed images reduce transfer time

Disk Image Types

  • .dmg - Apple Disk Image (primary format)
  • .iso - ISO 9660 format for cross-platform compatibility
  • .sparseimage - Sparse images that grow as needed
  • .sparsebundle - Bundle format for network storage

Basic Disk Image Creation

Simple Folder to Disk Image

#!/bin/bash

# Create basic disk image from folder
SOURCE_FOLDER="$1"
IMAGE_NAME="$2"
OUTPUT_PATH="$3"

if [[ -z "$SOURCE_FOLDER" || -z "$IMAGE_NAME" || -z "$OUTPUT_PATH" ]]; then
    echo "❌ Usage: $0 <source_folder> <image_name> <output_path>"
    echo "Example: $0 /Users/Shared MyImage /Users/username/Documents"
    exit 1
fi

# Validate source folder exists
if [[ ! -d "$SOURCE_FOLDER" ]]; then
    echo "❌ Source folder does not exist: $SOURCE_FOLDER"
    exit 1
fi

# Create output directory if it doesn't exist
mkdir -p "$OUTPUT_PATH"

echo "💿 Creating disk image from folder..."
echo "Source: $SOURCE_FOLDER"
echo "Image name: $IMAGE_NAME"
echo "Output: $OUTPUT_PATH/$IMAGE_NAME.dmg"

# Create the disk image
if hdiutil create -fs HFS+ -srcfolder "$SOURCE_FOLDER" -volname "$IMAGE_NAME" "$OUTPUT_PATH/$IMAGE_NAME.dmg"; then
    echo "✅ Disk image created successfully"
    
    # Get image size
    IMAGE_SIZE=$(du -h "$OUTPUT_PATH/$IMAGE_NAME.dmg" | cut -f1)
    echo "Image size: $IMAGE_SIZE"
    
    # Get source folder size for comparison
    SOURCE_SIZE=$(du -sh "$SOURCE_FOLDER" | cut -f1)
    echo "Source folder size: $SOURCE_SIZE"
else
    echo "❌ Failed to create disk image"
    exit 1
fi

Advanced Disk Image Creation

#!/bin/bash

# Advanced disk image creation with options
create_advanced_disk_image() {
    local source_folder="$1"
    local image_name="$2"
    local output_path="$3"
    local filesystem="${4:-HFS+}"
    local compression="${5:-UDBZ}"
    local encryption="${6:-false}"
    
    if [[ ! -d "$source_folder" ]]; then
        echo "❌ Source folder not found: $source_folder"
        return 1
    fi
    
    mkdir -p "$output_path"
    
    echo "💿 Creating advanced disk image..."
    echo "Source: $source_folder"
    echo "Filesystem: $filesystem"
    echo "Compression: $compression"
    echo "Encryption: $encryption"
    
    # Build hdiutil command
    local cmd="hdiutil create"
    cmd="$cmd -fs $filesystem"
    cmd="$cmd -srcfolder '$source_folder'"
    cmd="$cmd -volname '$image_name'"
    
    # Add compression if specified
    if [[ "$compression" != "none" ]]; then
        cmd="$cmd -format $compression"
    fi
    
    # Add encryption if requested
    if [[ "$encryption" == "true" ]]; then
        cmd="$cmd -encryption AES-256"
        cmd="$cmd -stdinpass"
        echo "🔐 Encryption enabled - you will be prompted for a password"
    fi
    
    cmd="$cmd '$output_path/$image_name.dmg'"
    
    # Execute command
    if [[ "$encryption" == "true" ]]; then
        echo "Enter password for disk image encryption:"
        read -s password
        echo "$password" | eval "$cmd"
    else
        eval "$cmd"
    fi
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Advanced disk image created successfully"
        
        # Display image information
        echo ""
        echo "=== Image Information ==="
        hdiutil imageinfo "$output_path/$image_name.dmg" | grep -E "Format|Compressed|Encrypted|Checksum"
        
        return 0
    else
        echo "❌ Failed to create disk image"
        return 1
    fi
}

# Usage examples
# create_advanced_disk_image "/Users/Shared" "SharedData" "/tmp" "HFS+" "UDBZ" "false"
# create_advanced_disk_image "/Applications/MyApp.app" "MyApp" "/tmp" "HFS+" "UDZO" "true"

Filesystem and Format Options

Supported Filesystems

#!/bin/bash

# Display available filesystem and format options
show_disk_image_options() {
    echo "=== Available Filesystems ==="
    echo "HFS+     - Mac OS Extended (default)"
    echo "HFS+J    - Mac OS Extended (Journaled)"
    echo "HFSX     - Mac OS Extended (Case-sensitive)"
    echo "JHFS+X   - Mac OS Extended (Case-sensitive, Journaled)"
    echo "MS-DOS   - FAT32 (compatible with Windows)"
    echo "UDF      - Universal Disk Format"
    echo "APFS     - Apple File System (macOS 10.13+)"
    echo ""
    
    echo "=== Image Format Options ==="
    echo "UDRO     - Read-only, smaller size"
    echo "UDCO     - ADC compressed (obsolete)"
    echo "UDZO     - zlib compressed (most common)"
    echo "UDBZ     - bzip2 compressed (better compression)"
    echo "ULFO     - lzfse compressed (macOS 10.11+)"
    echo "ULMO     - lzma compressed"
    echo "UFBI     - Entire device"
    echo "SPARSE   - Sparse image (grows as needed)"
    echo "SPARSEBUNDLE - Sparse bundle (network friendly)"
    echo ""
    
    echo "=== Encryption Options ==="
    echo "AES-128  - 128-bit AES encryption"
    echo "AES-256  - 256-bit AES encryption (recommended)"
}

# Create disk image with specific options
create_custom_disk_image() {
    local source="$1"
    local name="$2"
    local output="$3"
    local fs="$4"
    local format="$5"
    local encrypt="$6"
    
    echo "Creating custom disk image with:"
    echo "  Filesystem: $fs"
    echo "  Format: $format"
    echo "  Encryption: $encrypt"
    
    local cmd="hdiutil create -fs '$fs' -format '$format'"
    
    if [[ "$encrypt" != "none" ]]; then
        cmd="$cmd -encryption '$encrypt' -stdinpass"
    fi
    
    cmd="$cmd -srcfolder '$source' -volname '$name' '$output/$name.dmg'"
    
    if [[ "$encrypt" != "none" ]]; then
        echo "Enter encryption password:"
        read -s password
        echo "$password" | eval "$cmd"
    else
        eval "$cmd"
    fi
}

# Example usage
# show_disk_image_options
# create_custom_disk_image "/path/to/folder" "MyImage" "/output/path" "HFS+" "UDBZ" "AES-256"

Batch Disk Image Operations

Batch Image Creation

#!/bin/bash

# Batch create disk images from multiple folders
batch_create_disk_images() {
    local base_path="$1"
    local output_dir="$2"
    local filesystem="${3:-HFS+}"
    local format="${4:-UDBZ}"
    
    if [[ ! -d "$base_path" ]]; then
        echo "❌ Base path not found: $base_path"
        return 1
    fi
    
    mkdir -p "$output_dir"
    
    echo "🔄 Starting batch disk image creation..."
    echo "Base path: $base_path"
    echo "Output directory: $output_dir"
    echo "Filesystem: $filesystem"
    echo "Format: $format"
    echo ""
    
    local success_count=0
    local failed_count=0
    local total_size=0
    
    # Process each subdirectory
    find "$base_path" -type d -mindepth 1 -maxdepth 1 | while read -r folder; do
        local folder_name=$(basename "$folder")
        local image_path="$output_dir/${folder_name}.dmg"
        
        echo "Processing: $folder_name"
        
        # Skip if image already exists
        if [[ -f "$image_path" ]]; then
            echo "  ⏭️  Image already exists, skipping"
            continue
        fi
        
        # Create disk image
        if hdiutil create -fs "$filesystem" -format "$format" \
           -srcfolder "$folder" -volname "$folder_name" \
           "$image_path" >/dev/null 2>&1; then
            
            local size=$(du -h "$image_path" | cut -f1)
            echo "  ✅ Created successfully ($size)"
            ((success_count++))
            
            # Add to total size calculation
            local size_bytes=$(du -b "$image_path" | cut -f1)
            total_size=$((total_size + size_bytes))
        else
            echo "  ❌ Failed to create image"
            ((failed_count++))
        fi
    done
    
    echo ""
    echo "=== Batch Operation Summary ==="
    echo "Successful: $success_count"
    echo "Failed: $failed_count"
    echo "Total size: $(numfmt --to=iec $total_size)"
}

# Usage example
# batch_create_disk_images "/Users/Shared/Projects" "/tmp/project_images" "HFS+" "UDBZ"

Image Verification and Analysis

#!/bin/bash

# Verify and analyze disk images
verify_disk_image() {
    local image_path="$1"
    
    if [[ ! -f "$image_path" ]]; then
        echo "❌ Image file not found: $image_path"
        return 1
    fi
    
    echo "🔍 Verifying disk image: $(basename "$image_path")"
    
    # Basic image information
    echo ""
    echo "=== Basic Information ==="
    echo "File size: $(du -h "$image_path" | cut -f1)"
    echo "File type: $(file "$image_path" | cut -d: -f2- | xargs)"
    
    # Detailed image information
    echo ""
    echo "=== Detailed Image Information ==="
    hdiutil imageinfo "$image_path" | grep -E "Format|Partition|Compressed|Encrypted|Checksum|Total"
    
    # Verify image integrity
    echo ""
    echo "=== Integrity Verification ==="
    if hdiutil verify "$image_path" >/dev/null 2>&1; then
        echo "✅ Image integrity verified successfully"
    else
        echo "❌ Image integrity verification failed"
        return 1
    fi
    
    # Test mount capability
    echo ""
    echo "=== Mount Test ==="
    local mount_point=$(mktemp -d)
    
    if hdiutil attach "$image_path" -mountpoint "$mount_point" -nobrowse -quiet; then
        echo "✅ Image mounts successfully"
        
        # Get volume information
        echo "Volume info: $(df -h "$mount_point" | tail -1 | awk '{print $2 " total, " $3 " used, " $4 " available"}')"
        
        # Count contents
        local file_count=$(find "$mount_point" -type f | wc -l | xargs)
        local dir_count=$(find "$mount_point" -type d | wc -l | xargs)
        echo "Contents: $file_count files, $dir_count directories"
        
        # Unmount
        hdiutil detach "$mount_point" -quiet
        rmdir "$mount_point"
    else
        echo "❌ Image failed to mount"
        rmdir "$mount_point"
        return 1
    fi
    
    echo ""
    echo "✅ Image verification completed successfully"
    return 0
}

# Batch verification
verify_multiple_images() {
    local image_dir="$1"
    
    if [[ ! -d "$image_dir" ]]; then
        echo "❌ Image directory not found: $image_dir"
        return 1
    fi
    
    echo "🔍 Verifying all disk images in: $image_dir"
    echo ""
    
    local verified=0
    local failed=0
    
    find "$image_dir" -name "*.dmg" -type f | while read -r image; do
        echo "Verifying: $(basename "$image")"
        if verify_disk_image "$image" >/dev/null 2>&1; then
            echo "  ✅ Verified"
            ((verified++))
        else
            echo "  ❌ Failed"
            ((failed++))
        fi
    done
    
    echo ""
    echo "Verification complete: $verified passed, $failed failed"
}

Enterprise Disk Image Management

#!/bin/bash

# MacFleet Disk Image Management Tool
# Comprehensive disk image creation and management for enterprise environments

# Configuration
LOG_FILE="/var/log/macfleet_diskimage.log"
BACKUP_DIR="/var/backups/macfleet/images"
REPORT_DIR="/var/reports/macfleet/images"
CONFIG_FILE="/etc/macfleet/image_policy.conf"
TEMP_DIR="/tmp/macfleet_images"

# Default settings
DEFAULT_FILESYSTEM="HFS+"
DEFAULT_FORMAT="UDBZ"
DEFAULT_ENCRYPTION="AES-256"
ENABLE_COMPRESSION=true
ENABLE_VERIFICATION=true
MAX_IMAGE_SIZE="10G"
CLEANUP_TEMP_FILES=true

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

# Setup directories
setup_directories() {
    for dir in "$BACKUP_DIR" "$REPORT_DIR" "$(dirname "$CONFIG_FILE")" "$TEMP_DIR"; do
        if [[ ! -d "$dir" ]]; then
            sudo mkdir -p "$dir"
            log_action "Created directory: $dir"
        fi
    done
}

# Check available disk space
check_disk_space() {
    local target_dir="$1"
    local required_space="$2"  # in bytes
    
    local available_space=$(df "$target_dir" | tail -1 | awk '{print $4}')
    available_space=$((available_space * 1024))  # Convert to bytes
    
    if [[ "$available_space" -lt "$required_space" ]]; then
        echo "❌ Insufficient disk space"
        echo "Required: $(numfmt --to=iec $required_space)"
        echo "Available: $(numfmt --to=iec $available_space)"
        return 1
    fi
    
    return 0
}

# Create enterprise disk image with full logging and validation
create_enterprise_disk_image() {
    local source_path="$1"
    local image_name="$2"
    local output_dir="$3"
    local filesystem="${4:-$DEFAULT_FILESYSTEM}"
    local format="${5:-$DEFAULT_FORMAT}"
    local encrypt="${6:-false}"
    local description="$7"
    
    log_action "Starting enterprise disk image creation: $image_name"
    
    # Validation
    if [[ ! -d "$source_path" ]]; then
        echo "❌ Source path not found: $source_path"
        log_action "ERROR: Source path not found: $source_path"
        return 1
    fi
    
    # Calculate source size
    local source_size_bytes=$(du -sb "$source_path" | cut -f1)
    local source_size_human=$(du -sh "$source_path" | cut -f1)
    
    echo "📁 Source analysis:"
    echo "  Path: $source_path"
    echo "  Size: $source_size_human ($source_size_bytes bytes)"
    
    # Check disk space (estimate 2x source size for safety)
    local estimated_space=$((source_size_bytes * 2))
    if ! check_disk_space "$output_dir" "$estimated_space"; then
        log_action "ERROR: Insufficient disk space for image creation"
        return 1
    fi
    
    # Create output directory
    mkdir -p "$output_dir"
    
    local output_path="$output_dir/$image_name.dmg"
    local start_time=$(date +%s)
    
    echo ""
    echo "💿 Creating disk image..."
    echo "  Name: $image_name"
    echo "  Filesystem: $filesystem"
    echo "  Format: $format"
    echo "  Output: $output_path"
    
    # Build command
    local cmd="hdiutil create -fs '$filesystem' -format '$format'"
    cmd="$cmd -srcfolder '$source_path' -volname '$image_name'"
    
    # Add encryption if requested
    if [[ "$encrypt" == "true" ]]; then
        cmd="$cmd -encryption '$DEFAULT_ENCRYPTION' -stdinpass"
        echo "  Encryption: Enabled ($DEFAULT_ENCRYPTION)"
    fi
    
    cmd="$cmd '$output_path'"
    
    # Execute image creation
    local creation_success=false
    
    if [[ "$encrypt" == "true" ]]; then
        echo ""
        echo "🔐 Enter password for disk image encryption:"
        read -s password
        if echo "$password" | eval "$cmd" >/dev/null 2>&1; then
            creation_success=true
        fi
    else
        if eval "$cmd" >/dev/null 2>&1; then
            creation_success=true
        fi
    fi
    
    local end_time=$(date +%s)
    local duration=$((end_time - start_time))
    
    if [[ "$creation_success" == "true" ]]; then
        local image_size_bytes=$(du -b "$output_path" | cut -f1)
        local image_size_human=$(du -h "$output_path" | cut -f1)
        local compression_ratio=$(echo "scale=2; $image_size_bytes * 100 / $source_size_bytes" | bc)
        
        echo ""
        echo "✅ Disk image created successfully"
        echo "  Creation time: ${duration}s"
        echo "  Image size: $image_size_human"
        echo "  Compression ratio: ${compression_ratio}%"
        
        # Verify image if enabled
        if [[ "$ENABLE_VERIFICATION" == "true" ]]; then
            echo ""
            echo "🔍 Verifying image integrity..."
            if hdiutil verify "$output_path" >/dev/null 2>&1; then
                echo "✅ Image verification passed"
                log_action "Image created and verified: $image_name ($image_size_human)"
            else
                echo "❌ Image verification failed"
                log_action "ERROR: Image verification failed: $image_name"
                return 1
            fi
        fi
        
        # Generate image metadata
        create_image_metadata "$output_path" "$source_path" "$description"
        
        return 0
    else
        echo "❌ Failed to create disk image"
        log_action "ERROR: Failed to create disk image: $image_name"
        return 1
    fi
}

# Create metadata file for the image
create_image_metadata() {
    local image_path="$1"
    local source_path="$2"
    local description="$3"
    
    local metadata_file="${image_path%.dmg}.json"
    
    cat > "$metadata_file" << EOF
{
    "image_name": "$(basename "$image_path")",
    "creation_date": "$(date -Iseconds)",
    "source_path": "$source_path",
    "image_path": "$image_path",
    "description": "$description",
    "file_size": $(du -b "$image_path" | cut -f1),
    "file_size_human": "$(du -h "$image_path" | cut -f1)",
    "checksum_md5": "$(md5 -q "$image_path")",
    "checksum_sha256": "$(shasum -a 256 "$image_path" | cut -d' ' -f1)",
    "format_info": $(hdiutil imageinfo "$image_path" -plist | plutil -convert json -o - -)
}
EOF
    
    echo "📄 Metadata saved: $metadata_file"
}

# Generate comprehensive image report
generate_image_report() {
    local image_dir="${1:-$BACKUP_DIR}"
    local report_file="$REPORT_DIR/image_report_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "📊 Generating disk image report..."
    
    {
        echo "MacFleet Disk Image Management Report"
        echo "Generated: $(date)"
        echo "Image Directory: $image_dir"
        echo "======================================"
        echo ""
        
        if [[ ! -d "$image_dir" ]]; then
            echo "❌ Image directory not found: $image_dir"
            return 1
        fi
        
        # Count and analyze images
        local total_images=$(find "$image_dir" -name "*.dmg" -type f | wc -l)
        local total_size_bytes=0
        local verified_count=0
        local failed_count=0
        
        echo "=== Summary ==="
        echo "Total disk images: $total_images"
        
        if [[ "$total_images" -eq 0 ]]; then
            echo "No disk images found in directory"
            return 0
        fi
        
        echo ""
        echo "=== Image Details ==="
        printf "%-30s %-10s %-15s %-10s\n" "Name" "Size" "Format" "Status"
        printf "%-30s %-10s %-15s %-10s\n" "----" "----" "------" "------"
        
        find "$image_dir" -name "*.dmg" -type f | sort | while read -r image_path; do
            local image_name=$(basename "$image_path")
            local image_size=$(du -h "$image_path" | cut -f1)
            local image_size_bytes=$(du -b "$image_path" | cut -f1)
            
            # Get format info
            local format_info=$(hdiutil imageinfo "$image_path" 2>/dev/null | grep "Format Description" | cut -d: -f2- | xargs)
            if [[ -z "$format_info" ]]; then
                format_info="Unknown"
            fi
            
            # Verify integrity
            local status="Unknown"
            if hdiutil verify "$image_path" >/dev/null 2>&1; then
                status="✅ Valid"
                ((verified_count++))
            else
                status="❌ Failed"
                ((failed_count++))
            fi
            
            printf "%-30s %-10s %-15s %-10s\n" "$image_name" "$image_size" "$format_info" "$status"
            
            total_size_bytes=$((total_size_bytes + image_size_bytes))
        done
        
        echo ""
        echo "=== Statistics ==="
        echo "Total size: $(numfmt --to=iec $total_size_bytes)"
        echo "Verified images: $verified_count"
        echo "Failed verification: $failed_count"
        echo "Average size: $(numfmt --to=iec $((total_size_bytes / total_images)))"
        
        # Storage recommendations
        echo ""
        echo "=== Recommendations ==="
        if [[ "$failed_count" -gt 0 ]]; then
            echo "⚠️  $failed_count images failed verification - investigate and recreate"
        fi
        
        if [[ "$total_size_bytes" -gt $((50 * 1024 * 1024 * 1024)) ]]; then  # 50GB
            echo "💡 Consider archiving older images to free up space"
        fi
        
        echo "💡 Regular verification recommended for critical images"
        
    } > "$report_file"
    
    echo "📊 Report saved to: $report_file"
    log_action "Image report generated: $report_file"
}

# Main execution function
main() {
    local action="${1:-help}"
    local source="${2:-}"
    local name="${3:-}"
    local output="${4:-$BACKUP_DIR}"
    
    log_action "=== MacFleet Disk Image Management Started ==="
    
    setup_directories
    
    case "$action" in
        "create")
            if [[ -n "$source" && -n "$name" ]]; then
                create_enterprise_disk_image "$source" "$name" "$output"
            else
                echo "❌ Usage: $0 create <source_folder> <image_name> [output_dir]"
                echo "Example: $0 create /Users/Shared MyImage /tmp"
            fi
            ;;
        "batch")
            if [[ -n "$source" ]]; then
                batch_create_disk_images "$source" "$output"
            else
                echo "❌ Usage: $0 batch <base_folder> [output_dir]"
                echo "Example: $0 batch /Users/Shared/Projects /tmp/images"
            fi
            ;;
        "verify")
            if [[ -n "$source" ]]; then
                if [[ -f "$source" ]]; then
                    verify_disk_image "$source"
                elif [[ -d "$source" ]]; then
                    verify_multiple_images "$source"
                else
                    echo "❌ Path not found: $source"
                fi
            else
                echo "❌ Usage: $0 verify <image_file_or_directory>"
            fi
            ;;
        "report")
            generate_image_report "$source"
            ;;
        "info")
            if [[ -n "$source" && -f "$source" ]]; then
                echo "=== Image Information ==="
                hdiutil imageinfo "$source"
            else
                echo "❌ Usage: $0 info <image_file>"
            fi
            ;;
        "options")
            show_disk_image_options
            ;;
        "help"|*)
            echo "MacFleet Disk Image Management Tool"
            echo "Usage: $0 [action] [options]"
            echo ""
            echo "Actions:"
            echo "  create <source> <name> [output]  - Create disk image from folder"
            echo "  batch <base_dir> [output]        - Create images from all subdirectories"
            echo "  verify <image_or_dir>            - Verify image integrity"
            echo "  report [image_dir]               - Generate comprehensive report"
            echo "  info <image_file>                - Show detailed image information"
            echo "  options                          - Show available filesystem and format options"
            echo "  help                             - Show this help message"
            echo ""
            echo "Examples:"
            echo "  $0 create /Users/Shared MyData   # Create MyData.dmg from /Users/Shared"
            echo "  $0 batch /Applications /tmp       # Create images for all apps"
            echo "  $0 verify /tmp/MyData.dmg         # Verify single image"
            echo "  $0 report /tmp                    # Generate report for all images in /tmp"
            echo ""
            echo "Configuration:"
            echo "  Default filesystem: $DEFAULT_FILESYSTEM"
            echo "  Default format: $DEFAULT_FORMAT"
            echo "  Default encryption: $DEFAULT_ENCRYPTION"
            echo "  Verification enabled: $ENABLE_VERIFICATION"
            ;;
    esac
    
    log_action "=== MacFleet Disk Image Management Completed ==="
}

# Execute main function
main "$@"

Image Format Comparison

FormatCompressionSizeCompatibilityUse Case
UDRONoneLargeUniversalTesting, temporary images
UDZOzlib (good)MediummacOS 10.2+General purpose, good balance
UDBZbzip2 (better)SmallmacOS 10.4+Archive storage, slower access
ULFOlzfse (fast)SmallmacOS 10.11+Modern systems, fast compression
SPARSENoneVariablemacOSGrowing images, development

Security and Encryption

Encrypted Image Creation

# Create encrypted disk image with enterprise policies
create_secure_image() {
    local source="$1"
    local name="$2"
    local output="$3"
    local encryption_level="${4:-AES-256}"
    
    echo "🔐 Creating encrypted disk image..."
    echo "Encryption: $encryption_level"
    
    # Generate secure password if not provided
    if [[ -z "$IMAGE_PASSWORD" ]]; then
        echo "Enter encryption password (or set IMAGE_PASSWORD environment variable):"
        read -s IMAGE_PASSWORD
    fi
    
    echo "$IMAGE_PASSWORD" | hdiutil create \
        -fs HFS+ \
        -format UDBZ \
        -encryption "$encryption_level" \
        -stdinpass \
        -srcfolder "$source" \
        -volname "$name" \
        "$output/$name.dmg"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Encrypted image created successfully"
        echo "🔒 Image is protected with $encryption_level encryption"
    else
        echo "❌ Failed to create encrypted image"
        return 1
    fi
}

Important Notes

  • Disk Space - Ensure sufficient space for image creation (2x source size recommended)
  • Performance - Compression trades size for creation/access speed
  • Security - Use AES-256 encryption for sensitive data
  • Compatibility - Choose appropriate filesystem for target systems
  • Verification - Always verify critical images after creation
  • Enterprise Deployment - Test image mounting on target systems before bulk deployment

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.