- Complete Particle-OS rebranding from uBlue-OS - Professional installation system with standardized paths - Self-initialization system with --init and --reset commands - Enhanced error messages and dependency checking - Comprehensive testing infrastructure - All source scriptlets updated with runtime improvements - Clean codebase with redundant files moved to archive - Complete documentation suite
330 lines
9.8 KiB
Bash
330 lines
9.8 KiB
Bash
# Transaction management for Particle-OS apt-layer Tool
|
|
# Provides atomic operations with automatic rollback and recovery
|
|
|
|
# System initialization functions
|
|
initialize_particle_os_system() {
|
|
log_info "Initializing Particle-OS system..." "apt-layer"
|
|
|
|
# Create configuration directory
|
|
mkdir -p "/usr/local/etc/particle-os"
|
|
|
|
# Create workspace directory
|
|
mkdir -p "/var/lib/particle-os"
|
|
|
|
# Create log directory
|
|
mkdir -p "/var/log/particle-os"
|
|
|
|
# Create cache directory
|
|
mkdir -p "/var/cache/particle-os"
|
|
|
|
# Create configuration file if it doesn't exist
|
|
if [[ ! -f "/usr/local/etc/particle-config.sh" ]]; then
|
|
create_default_configuration
|
|
fi
|
|
|
|
# Set proper permissions
|
|
chmod 755 "/var/lib/particle-os"
|
|
chmod 755 "/var/log/particle-os"
|
|
chmod 755 "/var/cache/particle-os"
|
|
chmod 644 "/usr/local/etc/particle-config.sh"
|
|
|
|
log_success "Particle-OS system initialized successfully" "apt-layer"
|
|
}
|
|
|
|
create_default_configuration() {
|
|
log_info "Creating default configuration..." "apt-layer"
|
|
|
|
cat > "/usr/local/etc/particle-config.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# Particle-OS Configuration File
|
|
# Generated automatically on $(date)
|
|
|
|
# Core paths
|
|
export PARTICLE_WORKSPACE="/var/lib/particle-os"
|
|
export PARTICLE_CONFIG_DIR="/usr/local/etc/particle-os"
|
|
export PARTICLE_LOG_DIR="/var/log/particle-os"
|
|
export PARTICLE_CACHE_DIR="/var/cache/particle-os"
|
|
|
|
# Build and temporary directories
|
|
export PARTICLE_BUILD_DIR="$PARTICLE_WORKSPACE/build"
|
|
export PARTICLE_TEMP_DIR="$PARTICLE_WORKSPACE/temp"
|
|
export PARTICLE_BACKUP_DIR="$PARTICLE_WORKSPACE/backup"
|
|
|
|
# Layer management
|
|
export PARTICLE_LAYERS_DIR="$PARTICLE_WORKSPACE/layers"
|
|
export PARTICLE_IMAGES_DIR="$PARTICLE_WORKSPACE/images"
|
|
export PARTICLE_MOUNTS_DIR="$PARTICLE_WORKSPACE/mounts"
|
|
|
|
# ComposeFS integration
|
|
export PARTICLE_COMPOSEFS_DIR="$PARTICLE_WORKSPACE/composefs"
|
|
export PARTICLE_COMPOSEFS_SCRIPT="/usr/local/bin/composefs-alternative.sh"
|
|
|
|
# Boot management
|
|
export PARTICLE_BOOTC_SCRIPT="/usr/local/bin/bootc-alternative.sh"
|
|
export PARTICLE_BOOTUPD_SCRIPT="/usr/local/bin/bootupd-alternative.sh"
|
|
|
|
# Transaction management
|
|
export PARTICLE_TRANSACTION_LOG="$PARTICLE_LOG_DIR/transactions.log"
|
|
export PARTICLE_TRANSACTION_STATE="$PARTICLE_CACHE_DIR/transaction.state"
|
|
|
|
# Logging configuration
|
|
export PARTICLE_LOG_LEVEL="INFO"
|
|
export PARTICLE_LOG_FILE="$PARTICLE_LOG_DIR/apt-layer.log"
|
|
|
|
# Security settings
|
|
export PARTICLE_SIGNING_ENABLED="false"
|
|
export PARTICLE_VERIFY_SIGNATURES="false"
|
|
|
|
# Container settings
|
|
export PARTICLE_CONTAINER_RUNTIME="podman"
|
|
export PARTICLE_CHROOT_ENABLED="true"
|
|
|
|
# Default package sources
|
|
export PARTICLE_DEFAULT_SOURCES="main restricted universe multiverse"
|
|
|
|
# Performance settings
|
|
export PARTICLE_PARALLEL_JOBS="4"
|
|
export PARTICLE_CACHE_ENABLED="true"
|
|
|
|
# Load configuration if it exists
|
|
if [[ -f "$PARTICLE_CONFIG_DIR/particle-config.sh" ]]; then
|
|
source "$PARTICLE_CONFIG_DIR/particle-config.sh"
|
|
fi
|
|
EOF
|
|
|
|
log_success "Default configuration created: /usr/local/etc/particle-config.sh" "apt-layer"
|
|
}
|
|
|
|
reset_particle_os_system() {
|
|
log_warning "Resetting Particle-OS system..." "apt-layer"
|
|
|
|
# Backup existing configuration
|
|
if [[ -f "/usr/local/etc/particle-config.sh" ]]; then
|
|
cp "/usr/local/etc/particle-config.sh" "/usr/local/etc/particle-config.sh.backup.$(date +%Y%m%d_%H%M%S)"
|
|
log_info "Existing configuration backed up" "apt-layer"
|
|
fi
|
|
|
|
# Remove existing directories
|
|
rm -rf "/var/lib/particle-os"
|
|
rm -rf "/var/log/particle-os"
|
|
rm -rf "/var/cache/particle-os"
|
|
|
|
# Reinitialize system
|
|
initialize_particle_os_system
|
|
|
|
log_success "Particle-OS system reset successfully" "apt-layer"
|
|
}
|
|
|
|
# Transaction management functions
|
|
start_transaction() {
|
|
local operation="$1"
|
|
local target="$2"
|
|
|
|
TRANSACTION_ID=$(date +%Y%m%d_%H%M%S)_$$
|
|
TRANSACTION_PHASE="started"
|
|
TRANSACTION_TARGET="$target"
|
|
|
|
log_transaction "Starting transaction $TRANSACTION_ID: $operation -> $target" "apt-layer"
|
|
|
|
# Save transaction state
|
|
save_transaction_state
|
|
|
|
# Log transaction start
|
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) - START - $TRANSACTION_ID - $operation - $target" >> "$TRANSACTION_LOG"
|
|
}
|
|
|
|
update_transaction_phase() {
|
|
local phase="$1"
|
|
|
|
TRANSACTION_PHASE="$phase"
|
|
|
|
log_transaction "Transaction $TRANSACTION_ID phase: $phase" "apt-layer"
|
|
|
|
# Update transaction state
|
|
save_transaction_state
|
|
|
|
# Log phase update
|
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) - PHASE - $TRANSACTION_ID - $phase" >> "$TRANSACTION_LOG"
|
|
}
|
|
|
|
commit_transaction() {
|
|
log_transaction "Committing transaction $TRANSACTION_ID" "apt-layer"
|
|
|
|
# Log successful completion
|
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) - COMMIT - $TRANSACTION_ID - SUCCESS" >> "$TRANSACTION_LOG"
|
|
|
|
# Clear transaction state
|
|
clear_transaction_state
|
|
|
|
log_success "Transaction $TRANSACTION_ID completed successfully" "apt-layer"
|
|
}
|
|
|
|
rollback_transaction() {
|
|
log_transaction "Rolling back transaction $TRANSACTION_ID" "apt-layer"
|
|
|
|
if [[ -n "$TRANSACTION_BACKUP" ]] && [[ -d "$TRANSACTION_BACKUP" ]]; then
|
|
log_info "Restoring from backup: $TRANSACTION_BACKUP" "apt-layer"
|
|
|
|
# Restore from backup
|
|
if atomic_directory_swap "$TRANSACTION_BACKUP" "$TRANSACTION_TARGET" ""; then
|
|
log_success "Rollback completed successfully" "apt-layer"
|
|
else
|
|
log_error "Rollback failed - manual intervention may be required" "apt-layer"
|
|
fi
|
|
else
|
|
log_warning "No backup available for rollback" "apt-layer"
|
|
fi
|
|
|
|
# Log rollback
|
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) - ROLLBACK - $TRANSACTION_ID - $TRANSACTION_PHASE" >> "$TRANSACTION_LOG"
|
|
|
|
# Clear transaction state
|
|
clear_transaction_state
|
|
}
|
|
|
|
save_transaction_state() {
|
|
if [[ -n "$TRANSACTION_ID" ]]; then
|
|
cat > "$TRANSACTION_STATE" << EOF
|
|
TRANSACTION_ID="$TRANSACTION_ID"
|
|
TRANSACTION_PHASE="$TRANSACTION_PHASE"
|
|
TRANSACTION_TARGET="$TRANSACTION_TARGET"
|
|
TRANSACTION_BACKUP="$TRANSACTION_BACKUP"
|
|
TRANSACTION_TEMP_DIRS=(${TRANSACTION_TEMP_DIRS[*]})
|
|
EOF
|
|
fi
|
|
}
|
|
|
|
clear_transaction_state() {
|
|
TRANSACTION_ID=""
|
|
TRANSACTION_PHASE=""
|
|
TRANSACTION_TARGET=""
|
|
TRANSACTION_BACKUP=""
|
|
TRANSACTION_TEMP_DIRS=()
|
|
|
|
# Remove state file
|
|
rm -f "$TRANSACTION_STATE"
|
|
}
|
|
|
|
load_transaction_state() {
|
|
if [[ -f "$TRANSACTION_STATE" ]]; then
|
|
source "$TRANSACTION_STATE"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_incomplete_transactions() {
|
|
log_info "Checking for incomplete transactions..." "apt-layer"
|
|
|
|
if load_transaction_state; then
|
|
log_warning "Found incomplete transaction: $TRANSACTION_ID (phase: $TRANSACTION_PHASE)" "apt-layer"
|
|
log_info "Target: $TRANSACTION_TARGET" "apt-layer"
|
|
|
|
if [[ -n "$TRANSACTION_BACKUP" ]] && [[ -d "$TRANSACTION_BACKUP" ]]; then
|
|
log_info "Backup available: $TRANSACTION_BACKUP" "apt-layer"
|
|
fi
|
|
|
|
# Ask user what to do
|
|
echo
|
|
echo "Incomplete transaction detected. Choose an action:"
|
|
echo "1) Attempt rollback (recommended)"
|
|
echo "2) Continue transaction (risky)"
|
|
echo "3) Clear transaction state (manual cleanup required)"
|
|
echo "4) Exit"
|
|
echo
|
|
read -p "Enter choice (1-4): " choice
|
|
|
|
case "$choice" in
|
|
1)
|
|
log_info "Attempting rollback..." "apt-layer"
|
|
rollback_transaction
|
|
;;
|
|
2)
|
|
log_warning "Continuing incomplete transaction..." "apt-layer"
|
|
log_info "Transaction will resume from phase: $TRANSACTION_PHASE" "apt-layer"
|
|
;;
|
|
3)
|
|
log_warning "Clearing transaction state..." "apt-layer"
|
|
clear_transaction_state
|
|
;;
|
|
4)
|
|
log_info "Exiting..." "apt-layer"
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Invalid choice, exiting..." "apt-layer"
|
|
exit 1
|
|
;;
|
|
esac
|
|
else
|
|
log_info "No incomplete transactions found" "apt-layer"
|
|
fi
|
|
}
|
|
|
|
# Dry run functionality for package installation
|
|
dry_run_apt_install() {
|
|
local packages=("$@")
|
|
local chroot_dir="${1:-}"
|
|
|
|
log_info "Performing dry run for packages: ${packages[*]}" "apt-layer"
|
|
|
|
local apt_cmd
|
|
if [[ -n "$chroot_dir" ]]; then
|
|
apt_cmd="chroot '$chroot_dir' apt-get install --simulate"
|
|
else
|
|
apt_cmd="apt-get install --simulate"
|
|
fi
|
|
|
|
# Add packages to command
|
|
apt_cmd+=" ${packages[*]}"
|
|
|
|
log_debug "Running: $apt_cmd" "apt-layer"
|
|
|
|
# Execute dry run
|
|
if eval "$apt_cmd" >/dev/null 2>&1; then
|
|
log_success "Dry run completed successfully - no conflicts detected" "apt-layer"
|
|
return 0
|
|
else
|
|
log_error "Dry run failed - potential conflicts detected" "apt-layer"
|
|
log_info "Run the command manually to see detailed output:" "apt-layer"
|
|
log_info "$apt_cmd" "apt-layer"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Transaction logging utilities
|
|
log_transaction_event() {
|
|
local event="$1"
|
|
local details="$2"
|
|
|
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) - $event - $TRANSACTION_ID - $details" >> "$TRANSACTION_LOG"
|
|
}
|
|
|
|
# Transaction validation
|
|
validate_transaction_state() {
|
|
if [[ -z "$TRANSACTION_ID" ]]; then
|
|
log_error "No active transaction" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$TRANSACTION_TARGET" ]]; then
|
|
log_error "Transaction target not set" "apt-layer"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Transaction cleanup utilities
|
|
add_temp_directory() {
|
|
local temp_dir="$1"
|
|
TRANSACTION_TEMP_DIRS+=("$temp_dir")
|
|
save_transaction_state
|
|
}
|
|
|
|
add_backup_path() {
|
|
local backup_path="$1"
|
|
TRANSACTION_BACKUP="$backup_path"
|
|
save_transaction_state
|
|
}
|