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:
- Download - Fetch the ZIP file from a URL using
curl
- Extract - Unzip the contents using
unzip
- Install - Optionally install or move files to their final location
- 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
Issue | Solution |
---|---|
Download fails | Check URL accessibility and internet connection |
ZIP extraction errors | Verify ZIP file integrity with unzip -t |
Permission denied | Run script with admin privileges |
App not installing | Check for .app bundle in extracted contents |
Slow downloads | Increase 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