Install Latest Firefox Version on macOS Devices
This comprehensive guide demonstrates how to install and manage the latest Firefox version on macOS devices for enterprise deployment, automatic updates, and configuration management.
Overview
Firefox prioritizes user privacy, security, and provides extensive customization options for browsing according to organizational preferences, making it ideal for enterprise use. This guide provides scripts to ensure macOS devices are equipped with the latest Firefox version through automated installation and management.
Key Benefits
- Privacy-focused: Enhanced user privacy and data protection
- Security: Regular security updates and enterprise-grade protection
- Customization: Extensive configuration options for enterprise policies
- Cross-platform: Consistent experience across different operating systems
- Open source: Transparent development and security auditing
Basic Firefox Installation
Simple Firefox Installation Script
Create a basic script to install the latest Firefox version:
#!/bin/bash
# Basic Firefox installation script
# Usage: ./install_firefox.sh
install_firefox() {
echo "Starting Firefox installation process..."
# Check if Firefox is already installed
if [ -d "/Applications/Firefox.app" ]; then
echo "Firefox is already installed."
exit 0
fi
# Firefox download URL
firefox_url="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
download_dir="$HOME/Applications"
# Create download directory
mkdir -p "$download_dir"
echo "Downloading Firefox..."
curl -L -o "$download_dir/Firefox.dmg" "$firefox_url"
echo "Mounting the Firefox disk image..."
hdiutil attach "$download_dir/Firefox.dmg"
echo "Installing Firefox..."
cp -r "/Volumes/Firefox/Firefox.app" "/Applications/"
echo "Unmounting the Firefox disk image..."
hdiutil detach "/Volumes/Firefox"
echo "Cleaning up..."
rm "$download_dir/Firefox.dmg"
echo "Firefox installation complete."
}
# Execute installation
install_firefox
Enhanced Firefox Installation with Validation
#!/bin/bash
# Enhanced Firefox installation with validation and logging
# Usage: ./enhanced_firefox_install.sh
enhanced_firefox_install() {
local log_file="/var/log/macfleet_firefox_install.log"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
local download_dir="/tmp/macfleet_firefox"
# Create log directory
mkdir -p /var/log
mkdir -p "$download_dir"
echo "[$timestamp] Enhanced Firefox installation started" >> "$log_file"
# Check if running as root (recommended for enterprise deployment)
if [ "$EUID" -ne 0 ]; then
echo "Warning: Running as user. Some features may be limited."
echo "[$timestamp] Running as user, not root" >> "$log_file"
fi
# Check existing Firefox installation
check_existing_firefox
# Download and install Firefox
download_firefox
install_firefox_app
verify_installation
cleanup_installation
echo "[$timestamp] Enhanced Firefox installation completed" >> "$log_file"
}
check_existing_firefox() {
echo "Checking for existing Firefox installation..."
if [ -d "/Applications/Firefox.app" ]; then
local current_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
echo "Firefox is already installed (Version: $current_version)"
echo "[$timestamp] Firefox already installed - Version: $current_version" >> "$log_file"
read -p "Do you want to update to the latest version? (y/N): " update_choice
if [ "$update_choice" != "y" ] && [ "$update_choice" != "Y" ]; then
echo "Installation cancelled."
exit 0
fi
echo "Proceeding with Firefox update..."
else
echo "No existing Firefox installation found."
echo "[$timestamp] No existing Firefox installation found" >> "$log_file"
fi
}
download_firefox() {
echo "Downloading latest Firefox..."
local firefox_url="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
local firefox_dmg="$download_dir/Firefox.dmg"
# Check network connectivity
if ! ping -c 1 download.mozilla.org >/dev/null 2>&1; then
echo "Error: No network connectivity to Mozilla servers"
echo "[$timestamp] Network connectivity check failed" >> "$log_file"
exit 1
fi
# Download Firefox with progress and error handling
if curl -L --progress-bar -o "$firefox_dmg" "$firefox_url"; then
echo "Firefox download completed successfully"
echo "[$timestamp] Firefox download completed" >> "$log_file"
else
echo "Error: Failed to download Firefox"
echo "[$timestamp] Firefox download failed" >> "$log_file"
exit 1
fi
# Verify download
if [ -f "$firefox_dmg" ]; then
local file_size=$(stat -f%z "$firefox_dmg" 2>/dev/null || echo "0")
echo "Downloaded file size: $file_size bytes"
echo "[$timestamp] Downloaded file size: $file_size bytes" >> "$log_file"
if [ "$file_size" -lt 50000000 ]; then # Less than 50MB indicates potential issue
echo "Warning: Downloaded file seems too small. Possible download issue."
echo "[$timestamp] Downloaded file size warning" >> "$log_file"
fi
else
echo "Error: Download file not found"
echo "[$timestamp] Download file not found" >> "$log_file"
exit 1
fi
}
install_firefox_app() {
echo "Installing Firefox application..."
local firefox_dmg="$download_dir/Firefox.dmg"
local mount_point="/tmp/firefox_mount"
# Create mount point
mkdir -p "$mount_point"
# Mount the DMG file
if hdiutil attach "$firefox_dmg" -mountpoint "$mount_point" -quiet; then
echo "Firefox disk image mounted successfully"
echo "[$timestamp] Firefox disk image mounted" >> "$log_file"
else
echo "Error: Failed to mount Firefox disk image"
echo "[$timestamp] Failed to mount Firefox disk image" >> "$log_file"
exit 1
fi
# Copy Firefox application
if [ -d "$mount_point/Firefox.app" ]; then
echo "Copying Firefox application to /Applications..."
# Remove existing installation if present
if [ -d "/Applications/Firefox.app" ]; then
rm -rf "/Applications/Firefox.app"
fi
# Copy new Firefox application
if cp -R "$mount_point/Firefox.app" "/Applications/"; then
echo "Firefox application copied successfully"
echo "[$timestamp] Firefox application copied successfully" >> "$log_file"
else
echo "Error: Failed to copy Firefox application"
echo "[$timestamp] Failed to copy Firefox application" >> "$log_file"
hdiutil detach "$mount_point" -quiet
exit 1
fi
else
echo "Error: Firefox.app not found in disk image"
echo "[$timestamp] Firefox.app not found in disk image" >> "$log_file"
hdiutil detach "$mount_point" -quiet
exit 1
fi
# Unmount the disk image
if hdiutil detach "$mount_point" -quiet; then
echo "Firefox disk image unmounted successfully"
echo "[$timestamp] Firefox disk image unmounted" >> "$log_file"
else
echo "Warning: Failed to unmount Firefox disk image"
echo "[$timestamp] Failed to unmount Firefox disk image" >> "$log_file"
fi
}
verify_installation() {
echo "Verifying Firefox installation..."
if [ -d "/Applications/Firefox.app" ]; then
local installed_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
local bundle_id=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleIdentifier 2>/dev/null || echo "Unknown")
echo "Firefox installation verified:"
echo " Version: $installed_version"
echo " Bundle ID: $bundle_id"
echo " Location: /Applications/Firefox.app"
echo "[$timestamp] Firefox installation verified - Version: $installed_version" >> "$log_file"
# Test Firefox launch (optional)
echo "Testing Firefox launch..."
if timeout 10 /Applications/Firefox.app/Contents/MacOS/firefox --version >/dev/null 2>&1; then
echo "Firefox launch test successful"
echo "[$timestamp] Firefox launch test successful" >> "$log_file"
else
echo "Warning: Firefox launch test failed or timed out"
echo "[$timestamp] Firefox launch test failed" >> "$log_file"
fi
else
echo "Error: Firefox installation verification failed"
echo "[$timestamp] Firefox installation verification failed" >> "$log_file"
exit 1
fi
}
cleanup_installation() {
echo "Cleaning up installation files..."
if [ -d "$download_dir" ]; then
rm -rf "$download_dir"
echo "Installation files cleaned up"
echo "[$timestamp] Installation files cleaned up" >> "$log_file"
fi
}
# Execute enhanced installation
enhanced_firefox_install
Advanced Firefox Management
Enterprise Firefox Deployment Manager
#!/bin/bash
# Enterprise Firefox deployment manager
# Usage: ./enterprise_firefox_manager.sh
enterprise_firefox_manager() {
local config_file="/etc/macfleet/firefox_config.conf"
local log_file="/var/log/macfleet_firefox_enterprise.log"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root for enterprise deployment"
exit 1
fi
# Create configuration directory
mkdir -p /etc/macfleet
# Load or create configuration
if [ -f "$config_file" ]; then
source "$config_file"
else
create_enterprise_config
source "$config_file"
fi
echo "[$timestamp] Enterprise Firefox manager started" >> "$log_file"
# Display enterprise menu
display_enterprise_menu
}
create_enterprise_config() {
cat > "/etc/macfleet/firefox_config.conf" << 'EOF'
# MacFleet Enterprise Firefox Configuration
# Organization settings
ORGANIZATION_NAME="MacFleet Organization"
IT_CONTACT="support@macfleet.com"
# Firefox installation settings
FIREFOX_LANGUAGE="en-US"
FIREFOX_CHANNEL="release" # release, beta, nightly
AUTO_UPDATE_ENABLED="true"
SILENT_INSTALL="true"
# Enterprise policies
ENABLE_ENTERPRISE_POLICIES="true"
DISABLE_TELEMETRY="true"
DISABLE_STUDIES="true"
BLOCK_ABOUT_CONFIG="false"
HOMEPAGE_URL="https://www.macfleet.com"
# Security settings
ENABLE_SECURITY_POLICIES="true"
BLOCK_DANGEROUS_DOWNLOADS="true"
ENABLE_SAFE_BROWSING="true"
DISABLE_DEVELOPER_TOOLS="false"
# Network settings
PROXY_ENABLED="false"
PROXY_TYPE="system"
PROXY_HOST=""
PROXY_PORT=""
# Logging and monitoring
ENABLE_DETAILED_LOGGING="true"
LOG_RETENTION_DAYS="30"
SEND_DEPLOYMENT_REPORTS="true"
EOF
echo "configuration created at /etc/macfleet/firefox_config.conf"
}
display_enterprise_menu() {
while true; do
clear
echo "======================================="
echo "MacFleet Enterprise Firefox Manager"
echo "======================================="
echo ""
echo "Organization: $ORGANIZATION_NAME"
echo "Contact: $IT_CONTACT"
echo ""
echo "Available Actions:"
echo "1. Install/Update Firefox"
echo "2. Configure Enterprise Policies"
echo "3. Deploy to Multiple Devices"
echo "4. Check Firefox Status"
echo "5. Generate Deployment Report"
echo "6. Manage Firefox Profiles"
echo "7. View Configuration"
echo "8. Exit"
echo ""
read -p "Select an option (1-8): " choice
case $choice in
1)
install_update_firefox
;;
2)
configure_enterprise_policies
;;
3)
deploy_multiple_devices
;;
4)
check_firefox_status
;;
5)
generate_deployment_report
;;
6)
manage_firefox_profiles
;;
7)
view_configuration
;;
8)
echo "Exiting Enterprise Firefox Manager."
exit 0
;;
*)
echo "Invalid option. Please try again."
;;
esac
echo ""
read -p "Press Enter to continue..."
done
}
install_update_firefox() {
echo "======================================="
echo "Install/Update Firefox"
echo "======================================="
local current_version=""
if [ -d "/Applications/Firefox.app" ]; then
current_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
echo "Current Firefox version: $current_version"
else
echo "Firefox not currently installed"
fi
echo ""
echo "Installation options:"
echo "1. Install/Update to latest stable version"
echo "2. Install/Update to latest beta version"
echo "3. Install/Update to latest nightly version"
echo "4. Cancel"
echo ""
read -p "Select installation option (1-4): " install_choice
case $install_choice in
1)
install_firefox_version "release"
;;
2)
install_firefox_version "beta"
;;
3)
install_firefox_version "nightly"
;;
4)
echo "Installation cancelled."
;;
*)
echo "Invalid option."
;;
esac
}
install_firefox_version() {
local channel="$1"
local download_dir="/tmp/macfleet_firefox_enterprise"
echo "Installing Firefox $channel version..."
# Create download directory
mkdir -p "$download_dir"
# Determine download URL based on channel
local firefox_url
case $channel in
"release")
firefox_url="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=$FIREFOX_LANGUAGE"
;;
"beta")
firefox_url="https://download.mozilla.org/?product=firefox-beta-latest&os=osx&lang=$FIREFOX_LANGUAGE"
;;
"nightly")
firefox_url="https://download.mozilla.org/?product=firefox-nightly-latest&os=osx&lang=$FIREFOX_LANGUAGE"
;;
*)
echo "Error: Invalid Firefox channel"
return 1
;;
esac
echo "Downloading Firefox $channel..."
local firefox_dmg="$download_dir/Firefox-$channel.dmg"
if curl -L --progress-bar -o "$firefox_dmg" "$firefox_url"; then
echo "Download completed successfully"
echo "[$timestamp] Firefox $channel download completed" >> "$log_file"
else
echo "Error: Download failed"
echo "[$timestamp] Firefox $channel download failed" >> "$log_file"
return 1
fi
# Install Firefox
echo "Installing Firefox..."
local mount_point="/tmp/firefox_${channel}_mount"
mkdir -p "$mount_point"
if hdiutil attach "$firefox_dmg" -mountpoint "$mount_point" -quiet; then
# Remove existing installation
if [ -d "/Applications/Firefox.app" ]; then
rm -rf "/Applications/Firefox.app"
fi
# Copy new installation
if cp -R "$mount_point/Firefox.app" "/Applications/"; then
echo "Firefox $channel installed successfully"
echo "[$timestamp] Firefox $channel installed successfully" >> "$log_file"
# Apply enterprise policies if enabled
if [ "$ENABLE_ENTERPRISE_POLICIES" = "true" ]; then
apply_enterprise_policies
fi
else
echo "Error: Installation failed"
echo "[$timestamp] Firefox $channel installation failed" >> "$log_file"
fi
hdiutil detach "$mount_point" -quiet
else
echo "Error: Failed to mount disk image"
echo "[$timestamp] Failed to mount Firefox $channel disk image" >> "$log_file"
fi
# Cleanup
rm -rf "$download_dir"
}
configure_enterprise_policies() {
echo "======================================="
echo "Configure Enterprise Policies"
echo "======================================="
local policies_dir="/Applications/Firefox.app/Contents/Resources/distribution"
local policies_file="$policies_dir/policies.json"
echo "Creating enterprise policies configuration..."
# Create distribution directory
mkdir -p "$policies_dir"
# Generate policies.json
cat > "$policies_file" << EOF
{
"policies": {
"DisableTelemetry": $DISABLE_TELEMETRY,
"DisableFirefoxStudies": $DISABLE_STUDIES,
"BlockAboutConfig": $BLOCK_ABOUT_CONFIG,
"Homepage": {
"URL": "$HOMEPAGE_URL",
"Locked": true
},
"DisableSystemAddonUpdate": true,
"DisableAppUpdate": $([ "$AUTO_UPDATE_ENABLED" = "true" ] && echo "false" || echo "true"),
"NoDefaultBookmarks": true,
"OfferToSaveLogins": false,
"PasswordManagerEnabled": false,
"DisableDeveloperTools": $DISABLE_DEVELOPER_TOOLS,
"DisablePrivateBrowsing": false,
"DisableProfileImport": true,
"DisableFeedbackCommands": true,
"DisableFirefoxAccounts": false,
"DisableForgetButton": true,
"DisablePocket": true,
"DisableSetDesktopBackground": true,
"DisplayBookmarksToolbar": false,
"DontCheckDefaultBrowser": true,
"EnableTrackingProtection": {
"Value": true,
"Locked": true
}
}
}
EOF
echo "policies configuration created"
echo "[$timestamp] Enterprise policies configured" >> "$log_file"
# Set appropriate permissions
chmod 644 "$policies_file"
echo "policies applied to Firefox installation"
}
apply_enterprise_policies() {
echo "Applying enterprise policies..."
configure_enterprise_policies
}
check_firefox_status() {
echo "======================================="
echo "Firefox Status Report"
echo "======================================="
local device_name=$(scutil --get ComputerName)
local os_version=$(sw_vers -productVersion)
echo "Device: $device_name"
echo "macOS Version: $os_version"
echo "Timestamp: $(date)"
echo ""
if [ -d "/Applications/Firefox.app" ]; then
local firefox_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
local bundle_id=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleIdentifier 2>/dev/null || echo "Unknown")
echo "Firefox Status: INSTALLED"
echo "Version: $firefox_version"
echo "Bundle ID: $bundle_id"
echo "Installation Path: /Applications/Firefox.app"
# Check if Firefox is running
if pgrep -x "firefox" >/dev/null; then
echo "Process Status: RUNNING"
else
echo "Process Status: NOT RUNNING"
fi
# Check enterprise policies
local policies_file="/Applications/Firefox.app/Contents/Resources/distribution/policies.json"
if [ -f "$policies_file" ]; then
echo "Policies: CONFIGURED"
else
echo "Policies: NOT CONFIGURED"
fi
# Check application permissions
echo "Application Permissions:"
ls -la /Applications/Firefox.app | head -1
else
echo "Firefox Status: NOT INSTALLED"
fi
}
generate_deployment_report() {
echo "======================================="
echo "Generate Deployment Report"
echo "======================================="
local report_file="/tmp/firefox_deployment_report_$(date +%Y%m%d_%H%M%S).txt"
cat > "$report_file" << EOF
MacFleet Firefox Deployment Report
Generated: $(date)
Organization: $ORGANIZATION_NAME
Device Information:
Computer Name: $(scutil --get ComputerName)
macOS Version: $(sw_vers -productVersion)
Hardware Model: $(system_profiler SPHardwareDataType | grep "Model Name" | cut -d: -f2 | xargs)
Firefox Installation:
EOF
if [ -d "/Applications/Firefox.app" ]; then
local firefox_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
echo " Status: Installed" >> "$report_file"
echo " Version: $firefox_version" >> "$report_file"
echo " Installation Date: $(stat -f "%Sm" /Applications/Firefox.app)" >> "$report_file"
# Check enterprise policies
local policies_file="/Applications/Firefox.app/Contents/Resources/distribution/policies.json"
if [ -f "$policies_file" ]; then
echo " Enterprise Policies: Configured" >> "$report_file"
else
echo " Enterprise Policies: Not Configured" >> "$report_file"
fi
else
echo " Status: Not Installed" >> "$report_file"
fi
cat >> "$report_file" << EOF
Configuration:
Language: $FIREFOX_LANGUAGE
Channel: $FIREFOX_CHANNEL
Auto Update: $AUTO_UPDATE_ENABLED
Enterprise Policies: $ENABLE_ENTERPRISE_POLICIES
Contact: $IT_CONTACT
EOF
echo "Deployment report generated: $report_file"
}
manage_firefox_profiles() {
echo "======================================="
echo "Manage Firefox Profiles"
echo "======================================="
local profiles_dir="$HOME/Library/Application Support/Firefox/Profiles"
echo "Firefox profiles directory: $profiles_dir"
if [ -d "$profiles_dir" ]; then
echo "Found Firefox profiles:"
ls -la "$profiles_dir"
echo ""
echo "Profile management options:"
echo "1. List all profiles"
echo "2. Create new profile"
echo "3. Remove profile"
echo "4. Export profile"
echo "5. Import profile"
echo "6. Back to main menu"
read -p "Select option (1-6): " profile_choice
case $profile_choice in
1)
list_firefox_profiles
;;
2)
create_firefox_profile
;;
3)
remove_firefox_profile
;;
4)
export_firefox_profile
;;
5)
import_firefox_profile
;;
6)
return
;;
*)
echo "Invalid option."
;;
esac
else
echo "No Firefox profiles directory found."
echo "Firefox may not have been launched yet."
fi
}
list_firefox_profiles() {
echo "Firefox Profiles:"
/Applications/Firefox.app/Contents/MacOS/firefox -ProfileManager -no-remote &
sleep 2
pkill -f "firefox.*ProfileManager"
}
create_firefox_profile() {
read -p "Enter profile name: " profile_name
if [ -n "$profile_name" ]; then
/Applications/Firefox.app/Contents/MacOS/firefox -CreateProfile "$profile_name"
echo "Profile '$profile_name' created successfully"
else
echo "Profile name cannot be empty"
fi
}
remove_firefox_profile() {
echo "Warning: This will permanently delete the profile and all its data."
read -p "Enter profile name to remove: " profile_name
if [ -n "$profile_name" ]; then
read -p "Are you sure you want to remove profile '$profile_name'? (y/N): " confirm
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
# Profile removal logic would go here
echo "Profile removal functionality would be implemented here"
else
echo "Profile removal cancelled"
fi
fi
}
export_firefox_profile() {
echo "Profile export functionality would be implemented here"
}
import_firefox_profile() {
echo "Profile import functionality would be implemented here"
}
view_configuration() {
echo "======================================="
echo "Current Configuration"
echo "======================================="
if [ -f "/etc/macfleet/firefox_config.conf" ]; then
cat "/etc/macfleet/firefox_config.conf"
else
echo "No configuration file found."
fi
}
# Execute enterprise manager
enterprise_firefox_manager
Mass Deployment and Automation
Automated Firefox Update System
#!/bin/bash
# Automated Firefox update system
# Usage: ./automated_firefox_updater.sh
automated_firefox_updater() {
local config_file="/etc/macfleet/firefox_auto_update.conf"
local log_file="/var/log/macfleet_firefox_updates.log"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "Error: This script must be run as root"
exit 1
fi
# Create configuration if it doesn't exist
if [ ! -f "$config_file" ]; then
create_update_config
fi
source "$config_file"
echo "[$timestamp] Automated Firefox updater started" >> "$log_file"
# Check if updates are enabled
if [ "$ENABLE_AUTO_UPDATES" = "true" ]; then
check_and_update_firefox
else
echo "Automatic updates are disabled"
echo "[$timestamp] Automatic updates are disabled" >> "$log_file"
fi
}
create_update_config() {
mkdir -p /etc/macfleet
cat > "/etc/macfleet/firefox_auto_update.conf" << 'EOF'
# MacFleet Firefox Auto-Update Configuration
# Update settings
ENABLE_AUTO_UPDATES="true"
UPDATE_CHANNEL="release"
CHECK_INTERVAL="daily"
UPDATE_TIME="02:00"
# Safety settings
BACKUP_PROFILES="true"
BACKUP_RETENTION_DAYS="7"
REQUIRE_USER_CONSENT="false"
SKIP_IF_RUNNING="true"
# Notification settings
SEND_NOTIFICATIONS="true"
NOTIFICATION_EMAIL="admin@macfleet.com"
NOTIFY_ON_SUCCESS="true"
NOTIFY_ON_FAILURE="true"
# Enterprise settings
MAINTAIN_POLICIES="true"
PRESERVE_CUSTOMIZATIONS="true"
VERIFY_INSTALLATION="true"
EOF
echo "Auto-update configuration created at /etc/macfleet/firefox_auto_update.conf"
}
check_and_update_firefox() {
echo "[$timestamp] Checking for Firefox updates" >> "$log_file"
# Check if Firefox is installed
if [ ! -d "/Applications/Firefox.app" ]; then
echo "Firefox is not installed. Installing latest version..."
install_firefox_latest
return
fi
# Get current version
local current_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
# Check if Firefox is running and skip if configured
if [ "$SKIP_IF_RUNNING" = "true" ] && pgrep -x "firefox" >/dev/null; then
echo "Firefox is currently running. Skipping update."
echo "[$timestamp] Firefox is running - update skipped" >> "$log_file"
return
fi
# Create backup if enabled
if [ "$BACKUP_PROFILES" = "true" ]; then
backup_firefox_profiles
fi
# Download and check latest version
local download_dir="/tmp/macfleet_firefox_update"
mkdir -p "$download_dir"
local firefox_url="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
local firefox_dmg="$download_dir/Firefox-latest.dmg"
echo "Downloading latest Firefox version for comparison..."
if curl -L -s -o "$firefox_dmg" "$firefox_url"; then
# Mount and check version
local mount_point="/tmp/firefox_update_mount"
mkdir -p "$mount_point"
if hdiutil attach "$firefox_dmg" -mountpoint "$mount_point" -quiet; then
local latest_version=$(defaults read "$mount_point/Firefox.app/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "Unknown")
echo "Current version: $current_version"
echo "Latest version: $latest_version"
if [ "$current_version" != "$latest_version" ]; then
echo "Update available. Updating Firefox..."
echo "[$timestamp] Update available - Current: $current_version, Latest: $latest_version" >> "$log_file"
# Perform update
update_firefox_installation "$mount_point"
# Verify update
if verify_firefox_update "$latest_version"; then
echo "Firefox updated successfully to version $latest_version"
echo "[$timestamp] Firefox updated successfully to version $latest_version" >> "$log_file"
if [ "$SEND_NOTIFICATIONS" = "true" ] && [ "$NOTIFY_ON_SUCCESS" = "true" ]; then
send_update_notification "success" "$current_version" "$latest_version"
fi
else
echo "Firefox update verification failed"
echo "[$timestamp] Firefox update verification failed" >> "$log_file"
if [ "$SEND_NOTIFICATIONS" = "true" ] && [ "$NOTIFY_ON_FAILURE" = "true" ]; then
send_update_notification "failure" "$current_version" "$latest_version"
fi
fi
else
echo "Firefox is already up to date (version $current_version)"
echo "[$timestamp] Firefox is already up to date (version $current_version)" >> "$log_file"
fi
hdiutil detach "$mount_point" -quiet
else
echo "Failed to mount Firefox disk image"
echo "[$timestamp] Failed to mount Firefox disk image for update check" >> "$log_file"
fi
else
echo "Failed to download Firefox for version check"
echo "[$timestamp] Failed to download Firefox for version check" >> "$log_file"
fi
# Cleanup
rm -rf "$download_dir"
}
install_firefox_latest() {
echo "Installing latest Firefox version..."
local download_dir="/tmp/macfleet_firefox_install"
mkdir -p "$download_dir"
local firefox_url="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
local firefox_dmg="$download_dir/Firefox.dmg"
if curl -L --progress-bar -o "$firefox_dmg" "$firefox_url"; then
local mount_point="/tmp/firefox_install_mount"
mkdir -p "$mount_point"
if hdiutil attach "$firefox_dmg" -mountpoint "$mount_point" -quiet; then
if cp -R "$mount_point/Firefox.app" "/Applications/"; then
local installed_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
echo "Firefox installed successfully (version $installed_version)"
echo "[$timestamp] Firefox installed successfully (version $installed_version)" >> "$log_file"
# Apply enterprise policies if needed
if [ "$MAINTAIN_POLICIES" = "true" ]; then
apply_enterprise_policies
fi
else
echo "Failed to install Firefox"
echo "[$timestamp] Failed to install Firefox" >> "$log_file"
fi
hdiutil detach "$mount_point" -quiet
else
echo "Failed to mount Firefox disk image"
echo "[$timestamp] Failed to mount Firefox disk image for installation" >> "$log_file"
fi
else
echo "Failed to download Firefox"
echo "[$timestamp] Failed to download Firefox for installation" >> "$log_file"
fi
rm -rf "$download_dir"
}
update_firefox_installation() {
local mount_point="$1"
echo "Updating Firefox installation..."
# Remove old installation
if [ -d "/Applications/Firefox.app" ]; then
rm -rf "/Applications/Firefox.app"
fi
# Install new version
if cp -R "$mount_point/Firefox.app" "/Applications/"; then
echo "Firefox application updated successfully"
# Restore enterprise policies if enabled
if [ "$MAINTAIN_POLICIES" = "true" ]; then
apply_enterprise_policies
fi
# Preserve customizations if enabled
if [ "$PRESERVE_CUSTOMIZATIONS" = "true" ]; then
restore_customizations
fi
return 0
else
echo "Failed to update Firefox application"
return 1
fi
}
verify_firefox_update() {
local expected_version="$1"
if [ -d "/Applications/Firefox.app" ]; then
local actual_version=$(defaults read /Applications/Firefox.app/Contents/Info.plist CFBundleShortVersionString 2>/dev/null || echo "Unknown")
if [ "$actual_version" = "$expected_version" ]; then
return 0
else
echo "Version mismatch - Expected: $expected_version, Actual: $actual_version"
return 1
fi
else
echo "Firefox application not found after update"
return 1
fi
}
backup_firefox_profiles() {
echo "Creating backup of Firefox profiles..."
local profiles_dir="$HOME/Library/Application Support/Firefox"
local backup_dir="/var/backups/macfleet/firefox_profiles"
local backup_timestamp=$(date +%Y%m%d_%H%M%S)
mkdir -p "$backup_dir"
if [ -d "$profiles_dir" ]; then
if tar -czf "$backup_dir/firefox_profiles_backup_$backup_timestamp.tar.gz" -C "$HOME/Library/Application Support" "Firefox"; then
echo "Firefox profiles backed up successfully"
echo "[$timestamp] Firefox profiles backed up" >> "$log_file"
# Clean up old backups
find "$backup_dir" -name "firefox_profiles_backup_*.tar.gz" -mtime +$BACKUP_RETENTION_DAYS -delete
else
echo "Failed to backup Firefox profiles"
echo "[$timestamp] Failed to backup Firefox profiles" >> "$log_file"
fi
else
echo "Firefox profiles directory not found"
fi
}
send_update_notification() {
local status="$1"
local old_version="$2"
local new_version="$3"
local notification_title="MacFleet Firefox Update"
local notification_message
case $status in
"success")
notification_message="Firefox updated successfully from $old_version to $new_version"
;;
"failure")
notification_message="Firefox update failed - attempted to update from $old_version to $new_version"
;;
*)
notification_message="Firefox update status: $status"
;;
esac
# Use osascript to display notification
osascript -e "display notification \"$notification_message\" with title \"$notification_title\""
echo "[$timestamp] Update notification sent - Status: $status" >> "$log_file"
}
apply_enterprise_policies() {
echo "Applying enterprise policies..."
# This would call the enterprise policy configuration function
# Implementation depends on the specific policy requirements
}
restore_customizations() {
echo "Restoring customizations..."
# This would restore any custom configurations
# Implementation depends on the specific customization requirements
}
# Execute automated updater
automated_firefox_updater
Troubleshooting and Best Practices
Common Issues and Solutions
- Network Connectivity: Ensure stable internet connection for downloads
- Permissions: Run installation scripts with appropriate privileges
- Disk Space: Verify sufficient disk space before installation
- Existing Processes: Check for running Firefox processes before updates
- Enterprise Policies: Validate policy configurations after deployment
Best Practices
- Test Deployments: Always test in controlled environments first
- Backup Profiles: Create backups before major updates
- Monitor Installations: Use logging and monitoring for enterprise deployments
- Version Control: Track Firefox versions across your fleet
- Security Updates: Prioritize security updates and patches
Conclusion
Firefox deployment and management on macOS requires careful planning and execution. These scripts provide comprehensive solutions for installing, updating, and managing Firefox across Mac fleets. From basic installations to enterprise-grade automation, these tools ensure consistent and secure Firefox deployments while maintaining organizational policies and user preferences.