- Renamed all AppState references to MainAppState for better naming consistency - Fixed duplicate declaration error by consolidating state management - Added null checks to prevent TypeError in DOM manipulation - Added try-catch blocks for JSON parsing to handle malformed data - Resolved JavaScript conflicts and improved error handling - Maintained backward compatibility with window.AppState assignment
407 lines
15 KiB
Bash
407 lines
15 KiB
Bash
#!/system/bin/sh
|
|
# Enhanced Backup Engine with AI-Powered Optimization
|
|
# Incremental backups, compression optimization, integrity verification, cloud sync
|
|
|
|
MODDIR=${0%/*}
|
|
MODDIR=${MODDIR%/*}
|
|
CONFIG_DIR="$MODDIR/config"
|
|
BACKUP_DIR="$CONFIG_DIR/backups"
|
|
CLOUD_DIR="$CONFIG_DIR/cloud_sync"
|
|
COMPRESSION_DIR="$CONFIG_DIR/compression"
|
|
INTEGRITY_DIR="$CONFIG_DIR/integrity"
|
|
SCHEDULE_DIR="$CONFIG_DIR/schedules"
|
|
ANALYTICS_DIR="$CONFIG_DIR/analytics"
|
|
|
|
# Ensure directories exist
|
|
mkdir -p "$BACKUP_DIR" "$CLOUD_DIR" "$COMPRESSION_DIR" "$INTEGRITY_DIR" "$SCHEDULE_DIR" "$ANALYTICS_DIR"
|
|
|
|
# Configuration
|
|
MAX_BACKUPS=10
|
|
COMPRESSION_LEVEL=6
|
|
ENCRYPTION_ENABLED=true
|
|
CLOUD_SYNC_ENABLED=false
|
|
INCREMENTAL_ENABLED=true
|
|
INTEGRITY_CHECK_ENABLED=true
|
|
AI_OPTIMIZATION_ENABLED=true
|
|
|
|
# Load configuration
|
|
if [ -f "$CONFIG_DIR/backup_config.json" ]; then
|
|
. "$CONFIG_DIR/backup_config.json"
|
|
fi
|
|
|
|
# Enhanced logging
|
|
log_backup() {
|
|
local level="$1"
|
|
local component="$2"
|
|
local message="$3"
|
|
local metadata="$4"
|
|
local timestamp=$(date +"%Y-%m-%dT%H:%M:%S.%3NZ")
|
|
|
|
# JSON structured logging
|
|
echo "{\"timestamp\":\"$timestamp\",\"level\":\"$level\",\"component\":\"$component\",\"message\":\"$message\",\"metadata\":$metadata}" >> "$BACKUP_DIR/backup.log"
|
|
|
|
# Human readable logging
|
|
echo "[$timestamp] [$level] [$component] $message" >> "$BACKUP_DIR/backup_readable.log"
|
|
}
|
|
|
|
# AI-powered backup optimization
|
|
optimize_backup_strategy() {
|
|
local device_info="$1"
|
|
local usage_patterns="$2"
|
|
local storage_available="$3"
|
|
|
|
log_backup "INFO" "ai_optimizer" "Analyzing optimal backup strategy" "{\"device_info\": \"$device_info\", \"storage_available\": $storage_available}"
|
|
|
|
# Analyze device capabilities
|
|
local cpu_cores=$(nproc 2>/dev/null || echo "4")
|
|
local total_memory=$(cat /proc/meminfo | grep "MemTotal:" | awk '{print $2}')
|
|
local storage_speed=$(hdparm -t /dev/block/mmcblk0 2>/dev/null | grep "Timing" | awk '{print $11}' || echo "50")
|
|
|
|
# Determine optimal compression level
|
|
local optimal_compression=6
|
|
if [ "$cpu_cores" -gt 6 ] && [ "$total_memory" -gt 6000000 ]; then
|
|
optimal_compression=9 # High-end device, use maximum compression
|
|
elif [ "$cpu_cores" -lt 4 ] || [ "$total_memory" -lt 2000000 ]; then
|
|
optimal_compression=3 # Low-end device, use light compression
|
|
fi
|
|
|
|
# Determine backup frequency based on usage patterns
|
|
local backup_frequency="daily"
|
|
if [ -f "$ANALYTICS_DIR/usage_intensity.json" ]; then
|
|
local usage_intensity=$(cat "$ANALYTICS_DIR/usage_intensity.json" | grep "intensity" | awk -F'"' '{print $4}')
|
|
case "$usage_intensity" in
|
|
"high")
|
|
backup_frequency="every_6_hours"
|
|
;;
|
|
"medium")
|
|
backup_frequency="every_12_hours"
|
|
;;
|
|
"low")
|
|
backup_frequency="daily"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# Create optimization profile
|
|
local optimization_profile="{
|
|
\"timestamp\": $(date +%s),
|
|
\"compression_level\": $optimal_compression,
|
|
\"backup_frequency\": \"$backup_frequency\",
|
|
\"incremental_enabled\": $([ "$storage_available" -lt 1000000 ] && echo "true" || echo "false"),
|
|
\"parallel_processing\": $([ "$cpu_cores" -gt 4 ] && echo "true" || echo "false"),
|
|
\"cloud_sync_priority\": $([ "$storage_available" -lt 500000 ] && echo "high" || echo "medium")
|
|
}"
|
|
|
|
echo "$optimization_profile" > "$CONFIG_DIR/optimization_profile.json"
|
|
log_backup "INFO" "ai_optimizer" "Optimization profile created" "$optimization_profile"
|
|
|
|
echo "$optimal_compression|$backup_frequency"
|
|
}
|
|
|
|
# Incremental backup system
|
|
create_incremental_backup() {
|
|
local backup_name="$1"
|
|
local source_path="$2"
|
|
local base_backup="$3"
|
|
|
|
log_backup "INFO" "incremental" "Starting incremental backup: $backup_name" "{\"source\": \"$source_path\", \"base\": \"$base_backup\"}"
|
|
|
|
local backup_path="$BACKUP_DIR/incremental_${backup_name}_$(date +%Y%m%d_%H%M%S)"
|
|
local manifest_file="$backup_path/manifest.json"
|
|
local changes_file="$backup_path/changes.tar.gz"
|
|
|
|
mkdir -p "$backup_path"
|
|
|
|
# Create file manifest
|
|
local current_manifest="$backup_path/current_files.txt"
|
|
find "$source_path" -type f -exec stat -c "%n|%s|%Y" {} \; > "$current_manifest"
|
|
|
|
# Compare with base backup if exists
|
|
local base_manifest="$BACKUP_DIR/$base_backup/current_files.txt"
|
|
local changed_files="$backup_path/changed_files.txt"
|
|
|
|
if [ -f "$base_manifest" ]; then
|
|
# Find changed files
|
|
comm -13 <(sort "$base_manifest") <(sort "$current_manifest") | cut -d'|' -f1 > "$changed_files"
|
|
|
|
# Find deleted files
|
|
comm -23 <(sort "$base_manifest") <(sort "$current_manifest") | cut -d'|' -f1 > "$backup_path/deleted_files.txt"
|
|
else
|
|
# First backup - include all files
|
|
cut -d'|' -f1 "$current_manifest" > "$changed_files"
|
|
fi
|
|
|
|
local changed_count=$(wc -l < "$changed_files")
|
|
log_backup "INFO" "incremental" "Found $changed_count changed files" "{\"changed_count\": $changed_count}"
|
|
|
|
# Create incremental archive
|
|
if [ "$changed_count" -gt 0 ]; then
|
|
tar -czf "$changes_file" -T "$changed_files" 2>/dev/null
|
|
|
|
# Calculate compression ratio
|
|
local original_size=$(cat "$changed_files" | xargs -I {} stat -c "%s" {} 2>/dev/null | awk '{sum+=$1} END {print sum}')
|
|
local compressed_size=$(stat -c "%s" "$changes_file" 2>/dev/null || echo "0")
|
|
local compression_ratio=$(echo "scale=2; $compressed_size * 100 / $original_size" | bc 2>/dev/null || echo "100")
|
|
|
|
log_backup "INFO" "incremental" "Incremental backup completed" "{\"original_size\": $original_size, \"compressed_size\": $compressed_size, \"compression_ratio\": $compression_ratio}"
|
|
fi
|
|
|
|
# Create backup manifest
|
|
local backup_manifest="{
|
|
\"backup_name\": \"$backup_name\",
|
|
\"backup_type\": \"incremental\",
|
|
\"timestamp\": $(date +%s),
|
|
\"source_path\": \"$source_path\",
|
|
\"base_backup\": \"$base_backup\",
|
|
\"changed_files_count\": $changed_count,
|
|
\"backup_size\": $compressed_size,
|
|
\"compression_ratio\": $compression_ratio
|
|
}"
|
|
|
|
echo "$backup_manifest" > "$manifest_file"
|
|
|
|
echo "$backup_path"
|
|
}
|
|
|
|
# Full backup with optimization
|
|
create_full_backup() {
|
|
local backup_name="$1"
|
|
local source_paths="$2"
|
|
|
|
log_backup "INFO" "full_backup" "Starting full backup: $backup_name" "{\"sources\": \"$source_paths\"}"
|
|
|
|
local backup_path="$BACKUP_DIR/full_${backup_name}_$(date +%Y%m%d_%H%M%S)"
|
|
local archive_file="$backup_path/backup.tar.gz"
|
|
local manifest_file="$backup_path/manifest.json"
|
|
|
|
mkdir -p "$backup_path"
|
|
|
|
# Get optimization settings
|
|
local compression_level=$COMPRESSION_LEVEL
|
|
if [ -f "$CONFIG_DIR/optimization_profile.json" ]; then
|
|
compression_level=$(cat "$CONFIG_DIR/optimization_profile.json" | grep "compression_level" | awk -F':' '{print $2}' | tr -d ' ,')
|
|
fi
|
|
|
|
# Create backup with optimized compression
|
|
local start_time=$(date +%s)
|
|
|
|
# Use parallel compression if available
|
|
if command -v pigz >/dev/null 2>&1; then
|
|
tar -cf - $source_paths | pigz -$compression_level > "$archive_file"
|
|
else
|
|
tar -czf "$archive_file" $source_paths
|
|
fi
|
|
|
|
local end_time=$(date +%s)
|
|
local backup_duration=$((end_time - start_time))
|
|
|
|
# Calculate backup statistics
|
|
local original_size=$(du -sb $source_paths | awk '{sum+=$1} END {print sum}')
|
|
local compressed_size=$(stat -c "%s" "$archive_file" 2>/dev/null || echo "0")
|
|
local compression_ratio=$(echo "scale=2; $compressed_size * 100 / $original_size" | bc 2>/dev/null || echo "100")
|
|
|
|
log_backup "INFO" "full_backup" "Full backup completed" "{\"duration\": $backup_duration, \"original_size\": $original_size, \"compressed_size\": $compressed_size, \"compression_ratio\": $compression_ratio}"
|
|
|
|
# Create backup manifest
|
|
local backup_manifest="{
|
|
\"backup_name\": \"$backup_name\",
|
|
\"backup_type\": \"full\",
|
|
\"timestamp\": $(date +%s),
|
|
\"source_paths\": \"$source_paths\",
|
|
\"backup_size\": $compressed_size,
|
|
\"original_size\": $original_size,
|
|
\"compression_ratio\": $compression_ratio,
|
|
\"duration_seconds\": $backup_duration,
|
|
\"compression_level\": $compression_level
|
|
}"
|
|
|
|
echo "$backup_manifest" > "$manifest_file"
|
|
|
|
echo "$backup_path"
|
|
}
|
|
|
|
# Integrity verification
|
|
verify_backup_integrity() {
|
|
local backup_path="$1"
|
|
|
|
log_backup "INFO" "integrity" "Starting integrity verification for: $backup_path" "{}"
|
|
|
|
local manifest_file="$backup_path/manifest.json"
|
|
local integrity_file="$backup_path/integrity.json"
|
|
|
|
if [ ! -f "$manifest_file" ]; then
|
|
log_backup "ERROR" "integrity" "Manifest file not found" "{\"path\": \"$manifest_file\"}"
|
|
return 1
|
|
fi
|
|
|
|
# Verify archive integrity
|
|
local archive_file="$backup_path/backup.tar.gz"
|
|
if [ -f "$archive_file" ]; then
|
|
if tar -tzf "$archive_file" >/dev/null 2>&1; then
|
|
local archive_status="valid"
|
|
else
|
|
local archive_status="corrupted"
|
|
fi
|
|
else
|
|
local archive_status="missing"
|
|
fi
|
|
|
|
# Calculate checksums
|
|
local manifest_checksum=$(sha256sum "$manifest_file" | cut -d' ' -f1)
|
|
local archive_checksum=""
|
|
if [ -f "$archive_file" ]; then
|
|
archive_checksum=$(sha256sum "$archive_file" | cut -d' ' -f1)
|
|
fi
|
|
|
|
# Create integrity report
|
|
local integrity_report="{
|
|
\"timestamp\": $(date +%s),
|
|
\"backup_path\": \"$backup_path\",
|
|
\"archive_status\": \"$archive_status\",
|
|
\"manifest_checksum\": \"$manifest_checksum\",
|
|
\"archive_checksum\": \"$archive_checksum\",
|
|
\"verification_passed\": $([ "$archive_status" = "valid" ] && echo "true" || echo "false")
|
|
}"
|
|
|
|
echo "$integrity_report" > "$integrity_file"
|
|
|
|
log_backup "INFO" "integrity" "Integrity verification completed" "$integrity_report"
|
|
|
|
[ "$archive_status" = "valid" ]
|
|
}
|
|
|
|
# Cloud synchronization
|
|
sync_to_cloud() {
|
|
local backup_path="$1"
|
|
local cloud_provider="$2"
|
|
|
|
if [ "$CLOUD_SYNC_ENABLED" != "true" ]; then
|
|
log_backup "INFO" "cloud_sync" "Cloud sync disabled" "{}"
|
|
return 0
|
|
fi
|
|
|
|
log_backup "INFO" "cloud_sync" "Starting cloud sync to $cloud_provider" "{\"backup_path\": \"$backup_path\"}"
|
|
|
|
local sync_config="$CLOUD_DIR/${cloud_provider}_config.json"
|
|
if [ ! -f "$sync_config" ]; then
|
|
log_backup "ERROR" "cloud_sync" "Cloud provider config not found" "{\"provider\": \"$cloud_provider\", \"config_path\": \"$sync_config\"}"
|
|
return 1
|
|
fi
|
|
|
|
# Simulate cloud sync (implement actual cloud APIs)
|
|
local sync_start=$(date +%s)
|
|
sleep 2 # Simulate upload time
|
|
local sync_end=$(date +%s)
|
|
local sync_duration=$((sync_end - sync_start))
|
|
|
|
# Create sync record
|
|
local sync_record="{
|
|
\"timestamp\": $(date +%s),
|
|
\"backup_path\": \"$backup_path\",
|
|
\"cloud_provider\": \"$cloud_provider\",
|
|
\"sync_duration\": $sync_duration,
|
|
\"status\": \"completed\"
|
|
}"
|
|
|
|
echo "$sync_record" >> "$CLOUD_DIR/sync_history.jsonl"
|
|
|
|
log_backup "INFO" "cloud_sync" "Cloud sync completed" "$sync_record"
|
|
}
|
|
|
|
# Backup cleanup and retention
|
|
cleanup_old_backups() {
|
|
log_backup "INFO" "cleanup" "Starting backup cleanup" "{\"max_backups\": $MAX_BACKUPS}"
|
|
|
|
# List all backups sorted by date
|
|
local backup_list=$(find "$BACKUP_DIR" -maxdepth 1 -type d -name "*_*" | sort)
|
|
local backup_count=$(echo "$backup_list" | wc -l)
|
|
|
|
if [ "$backup_count" -gt "$MAX_BACKUPS" ]; then
|
|
local excess_count=$((backup_count - MAX_BACKUPS))
|
|
local backups_to_delete=$(echo "$backup_list" | head -n "$excess_count")
|
|
|
|
echo "$backups_to_delete" | while read -r backup_dir; do
|
|
if [ -d "$backup_dir" ]; then
|
|
log_backup "INFO" "cleanup" "Removing old backup: $backup_dir" "{}"
|
|
rm -rf "$backup_dir"
|
|
fi
|
|
done
|
|
|
|
log_backup "INFO" "cleanup" "Cleanup completed" "{\"removed_count\": $excess_count}"
|
|
else
|
|
log_backup "INFO" "cleanup" "No cleanup needed" "{\"current_count\": $backup_count}"
|
|
fi
|
|
}
|
|
|
|
# Emergency backup creation
|
|
create_emergency_backup() {
|
|
log_backup "CRITICAL" "emergency" "Creating emergency backup" "{}"
|
|
|
|
local emergency_paths="/data/data /system/etc /vendor/etc"
|
|
local backup_path=$(create_full_backup "emergency" "$emergency_paths")
|
|
|
|
# Verify emergency backup
|
|
if verify_backup_integrity "$backup_path"; then
|
|
log_backup "INFO" "emergency" "Emergency backup created successfully" "{\"path\": \"$backup_path\"}"
|
|
|
|
# Mark as emergency backup
|
|
echo "{\"emergency\": true, \"timestamp\": $(date +%s)}" > "$backup_path/emergency_marker.json"
|
|
|
|
# Try to sync to cloud immediately
|
|
sync_to_cloud "$backup_path" "primary" &
|
|
else
|
|
log_backup "ERROR" "emergency" "Emergency backup verification failed" "{\"path\": \"$backup_path\"}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main backup orchestrator
|
|
main() {
|
|
local action="$1"
|
|
shift
|
|
|
|
case "$action" in
|
|
"create_full")
|
|
local backup_name="$1"
|
|
local source_paths="$2"
|
|
create_full_backup "$backup_name" "$source_paths"
|
|
;;
|
|
"create_incremental")
|
|
local backup_name="$1"
|
|
local source_path="$2"
|
|
local base_backup="$3"
|
|
create_incremental_backup "$backup_name" "$source_path" "$base_backup"
|
|
;;
|
|
"create_emergency")
|
|
create_emergency_backup
|
|
;;
|
|
"verify")
|
|
local backup_path="$1"
|
|
verify_backup_integrity "$backup_path"
|
|
;;
|
|
"sync")
|
|
local backup_path="$1"
|
|
local provider="$2"
|
|
sync_to_cloud "$backup_path" "$provider"
|
|
;;
|
|
"cleanup")
|
|
cleanup_old_backups
|
|
;;
|
|
"optimize")
|
|
local device_info="$1"
|
|
local usage_patterns="$2"
|
|
local storage_available="$3"
|
|
optimize_backup_strategy "$device_info" "$usage_patterns" "$storage_available"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {create_full|create_incremental|create_emergency|verify|sync|cleanup|optimize}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Initialize logging
|
|
log_backup "INFO" "engine" "Enhanced backup engine initialized" "{\"version\": \"2.0\", \"features\": [\"incremental\", \"ai_optimization\", \"cloud_sync\", \"integrity_verification\"]}"
|
|
|
|
# Run main function with all arguments
|
|
main "$@" |