- 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
354 lines
No EOL
12 KiB
Bash
354 lines
No EOL
12 KiB
Bash
#!/bin/bash
|
|
|
|
# Particle-OS Unified Configuration
|
|
# This file provides consistent configuration for all Particle-OS scripts
|
|
# Source this file in other scripts: source /usr/local/etc/particle-config.sh
|
|
|
|
set -euo pipefail
|
|
|
|
# =============================================================================
|
|
# CORE CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Base directories
|
|
PARTICLE_ROOT="/var/lib/particle-os"
|
|
PARTICLE_CONFIG_DIR="/usr/local/etc/particle-os"
|
|
PARTICLE_LOG_DIR="/var/log/particle-os"
|
|
PARTICLE_CACHE_DIR="/var/cache/particle-os"
|
|
|
|
# Script locations
|
|
PARTICLE_SCRIPTS_DIR="/usr/local/bin"
|
|
COMPOSEFS_SCRIPT="$PARTICLE_SCRIPTS_DIR/composefs"
|
|
BOOTUPD_SCRIPT="$PARTICLE_SCRIPTS_DIR/bootupd"
|
|
APT_LAYER_SCRIPT="$PARTICLE_SCRIPTS_DIR/apt-layer"
|
|
|
|
# ComposeFS configuration
|
|
COMPOSEFS_DIR="/var/lib/composefs-alternative"
|
|
COMPOSEFS_IMAGES_DIR="$COMPOSEFS_DIR/images"
|
|
COMPOSEFS_LAYERS_DIR="$COMPOSEFS_DIR/layers"
|
|
COMPOSEFS_MOUNTS_DIR="$COMPOSEFS_DIR/mounts"
|
|
|
|
# Build and workspace directories
|
|
PARTICLE_BUILD_DIR="$PARTICLE_ROOT/build"
|
|
PARTICLE_WORKSPACE_DIR="$PARTICLE_ROOT/workspace"
|
|
PARTICLE_TEMP_DIR="$PARTICLE_ROOT/temp"
|
|
|
|
# Live overlay configuration
|
|
PARTICLE_LIVE_OVERLAY_DIR="$PARTICLE_ROOT/live-overlay"
|
|
PARTICLE_LIVE_UPPER_DIR="$PARTICLE_LIVE_OVERLAY_DIR/upper"
|
|
PARTICLE_LIVE_WORK_DIR="$PARTICLE_LIVE_OVERLAY_DIR/work"
|
|
|
|
# Transaction management
|
|
PARTICLE_TRANSACTION_LOG="$PARTICLE_LOG_DIR/transaction.log"
|
|
PARTICLE_TRANSACTION_STATE="$PARTICLE_ROOT/transaction.state"
|
|
PARTICLE_TRANSACTION_BACKUP_DIR="$PARTICLE_ROOT/backups"
|
|
|
|
# =============================================================================
|
|
# LOGGING CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Log levels: DEBUG, INFO, WARNING, ERROR
|
|
PARTICLE_LOG_LEVEL="${PARTICLE_LOG_LEVEL:-INFO}"
|
|
|
|
# Log file paths
|
|
PARTICLE_MAIN_LOG="$PARTICLE_LOG_DIR/particle.log"
|
|
COMPOSEFS_LOG="$PARTICLE_LOG_DIR/composefs.log"
|
|
BOOTUPD_LOG="$PARTICLE_LOG_DIR/bootupd.log"
|
|
APT_LAYER_LOG="$PARTICLE_LOG_DIR/apt-layer.log"
|
|
|
|
# Log rotation settings
|
|
PARTICLE_LOG_MAX_SIZE="100M"
|
|
PARTICLE_LOG_MAX_FILES=5
|
|
PARTICLE_LOG_COMPRESSION="${PARTICLE_LOG_COMPRESSION:-gzip}"
|
|
PARTICLE_LOG_FILES_PATTERN="${PARTICLE_LOG_FILES_PATTERN:-*.log}"
|
|
|
|
# =============================================================================
|
|
# SECURITY CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# GPG key for signing
|
|
PARTICLE_SIGNING_KEY="${PARTICLE_SIGNING_KEY:-}"
|
|
PARTICLE_SIGNING_KEYRING="${PARTICLE_SIGNING_KEYRING:-/etc/apt/trusted.gpg}"
|
|
|
|
# Secure Boot configuration
|
|
PARTICLE_SECURE_BOOT_ENABLED="${PARTICLE_SECURE_BOOT_ENABLED:-false}"
|
|
PARTICLE_SB_KEYS_DIR="$PARTICLE_CONFIG_DIR/secure-boot"
|
|
|
|
# =============================================================================
|
|
# PERFORMANCE CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Parallel processing
|
|
PARTICLE_PARALLEL_JOBS="${PARTICLE_PARALLEL_JOBS:-$(nproc 2>/dev/null || echo 4)}"
|
|
PARTICLE_MAX_PARALLEL_JOBS=8
|
|
|
|
# Compression settings
|
|
PARTICLE_SQUASHFS_COMPRESSION="${PARTICLE_SQUASHFS_COMPRESSION:-xz}"
|
|
PARTICLE_SQUASHFS_BLOCK_SIZE="${PARTICLE_SQUASHFS_BLOCK_SIZE:-1M}"
|
|
|
|
# Cache settings
|
|
PARTICLE_APT_CACHE_DIR="$PARTICLE_CACHE_DIR/apt"
|
|
PARTICLE_CONTAINER_CACHE_DIR="$PARTICLE_CACHE_DIR/containers"
|
|
|
|
# =============================================================================
|
|
# CONTAINER CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Container runtime preference
|
|
PARTICLE_CONTAINER_RUNTIME="${PARTICLE_CONTAINER_RUNTIME:-podman}"
|
|
|
|
# Container registry settings
|
|
PARTICLE_REGISTRY_URL="${PARTICLE_REGISTRY_URL:-}"
|
|
PARTICLE_REGISTRY_USERNAME="${PARTICLE_REGISTRY_USERNAME:-}"
|
|
PARTICLE_REGISTRY_PASSWORD="${PARTICLE_REGISTRY_PASSWORD:-}"
|
|
|
|
# =============================================================================
|
|
# NETWORK CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Package repository mirrors
|
|
PARTICLE_APT_MIRRORS=(
|
|
"http://archive.ubuntu.com/ubuntu/"
|
|
"http://security.ubuntu.com/ubuntu/"
|
|
)
|
|
|
|
# Proxy settings (if needed)
|
|
PARTICLE_HTTP_PROXY="${PARTICLE_HTTP_PROXY:-}"
|
|
PARTICLE_HTTPS_PROXY="${PARTICLE_HTTPS_PROXY:-}"
|
|
PARTICLE_NO_PROXY="${PARTICLE_NO_PROXY:-localhost,127.0.0.1}"
|
|
|
|
# =============================================================================
|
|
# VALIDATION FUNCTIONS
|
|
# =============================================================================
|
|
|
|
# Validate configuration
|
|
validate_particle_config() {
|
|
local errors=0
|
|
|
|
# Check required directories
|
|
for dir in "$PARTICLE_ROOT" "$PARTICLE_CONFIG_DIR" "$PARTICLE_LOG_DIR" "$PARTICLE_CACHE_DIR"; do
|
|
if [[ ! -d "$dir" ]]; then
|
|
echo "ERROR: Required directory does not exist: $dir" >&2
|
|
errors=$((errors + 1))
|
|
fi
|
|
done
|
|
|
|
# Check required scripts
|
|
for script in "$COMPOSEFS_SCRIPT" "$BOOTUPD_SCRIPT" "$APT_LAYER_SCRIPT"; do
|
|
if [[ ! -f "$script" ]]; then
|
|
echo "WARNING: Script not found: $script" >&2
|
|
elif [[ ! -x "$script" ]]; then
|
|
echo "WARNING: Script not executable: $script" >&2
|
|
fi
|
|
done
|
|
|
|
# Validate log level
|
|
case "$PARTICLE_LOG_LEVEL" in
|
|
DEBUG|INFO|WARNING|ERROR)
|
|
;;
|
|
*)
|
|
echo "ERROR: Invalid log level: $PARTICLE_LOG_LEVEL" >&2
|
|
errors=$((errors + 1))
|
|
;;
|
|
esac
|
|
|
|
# Validate compression
|
|
case "$PARTICLE_SQUASHFS_COMPRESSION" in
|
|
gzip|lzo|xz|zstd)
|
|
;;
|
|
*)
|
|
echo "ERROR: Invalid compression: $PARTICLE_SQUASHFS_COMPRESSION" >&2
|
|
errors=$((errors + 1))
|
|
;;
|
|
esac
|
|
|
|
# Validate container runtime
|
|
if [[ -n "$PARTICLE_CONTAINER_RUNTIME" ]]; then
|
|
if ! command -v "$PARTICLE_CONTAINER_RUNTIME" >/dev/null 2>&1; then
|
|
echo "WARNING: Container runtime not found: $PARTICLE_CONTAINER_RUNTIME" >&2
|
|
fi
|
|
fi
|
|
|
|
if [[ $errors -gt 0 ]]; then
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# =============================================================================
|
|
# INITIALIZATION FUNCTIONS
|
|
# =============================================================================
|
|
|
|
# Initialize Particle-OS environment
|
|
init_particle_environment() {
|
|
# Create required directories
|
|
mkdir -p "$PARTICLE_ROOT" "$PARTICLE_CONFIG_DIR" "$PARTICLE_LOG_DIR" "$PARTICLE_CACHE_DIR"
|
|
mkdir -p "$PARTICLE_BUILD_DIR" "$PARTICLE_WORKSPACE_DIR" "$PARTICLE_TEMP_DIR"
|
|
mkdir -p "$PARTICLE_LIVE_OVERLAY_DIR" "$PARTICLE_LIVE_UPPER_DIR" "$PARTICLE_LIVE_WORK_DIR"
|
|
mkdir -p "$PARTICLE_TRANSACTION_BACKUP_DIR"
|
|
mkdir -p "$PARTICLE_APT_CACHE_DIR" "$PARTICLE_CONTAINER_CACHE_DIR"
|
|
|
|
# Set proper permissions
|
|
chmod 755 "$PARTICLE_ROOT" "$PARTICLE_CONFIG_DIR" "$PARTICLE_LOG_DIR" "$PARTICLE_CACHE_DIR"
|
|
chmod 700 "$PARTICLE_TRANSACTION_BACKUP_DIR"
|
|
|
|
# Initialize log files if they don't exist
|
|
for log_file in "$PARTICLE_MAIN_LOG" "$COMPOSEFS_LOG" "$BOOTUPD_LOG" "$APT_LAYER_LOG"; do
|
|
if [[ ! -f "$log_file" ]]; then
|
|
touch "$log_file"
|
|
chmod 644 "$log_file"
|
|
fi
|
|
done
|
|
|
|
# Validate configuration
|
|
if ! validate_particle_config; then
|
|
echo "WARNING: Configuration validation failed" >&2
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# LOGGING FUNCTIONS
|
|
# =============================================================================
|
|
|
|
# Log levels
|
|
PARTICLE_LOG_DEBUG=0
|
|
PARTICLE_LOG_INFO=1
|
|
PARTICLE_LOG_WARNING=2
|
|
PARTICLE_LOG_ERROR=3
|
|
|
|
# Get numeric log level
|
|
get_log_level() {
|
|
case "$PARTICLE_LOG_LEVEL" in
|
|
DEBUG) echo $PARTICLE_LOG_DEBUG ;;
|
|
INFO) echo $PARTICLE_LOG_INFO ;;
|
|
WARNING) echo $PARTICLE_LOG_WARNING ;;
|
|
ERROR) echo $PARTICLE_LOG_ERROR ;;
|
|
*) echo $PARTICLE_LOG_INFO ;;
|
|
esac
|
|
}
|
|
|
|
# Check if should log at given level
|
|
should_log() {
|
|
local level="$1"
|
|
local current_level
|
|
current_level=$(get_log_level)
|
|
|
|
case "$level" in
|
|
DEBUG) [[ $current_level -le $PARTICLE_LOG_DEBUG ]] ;;
|
|
INFO) [[ $current_level -le $PARTICLE_LOG_INFO ]] ;;
|
|
WARNING) [[ $current_level -le $PARTICLE_LOG_WARNING ]] ;;
|
|
ERROR) [[ $current_level -le $PARTICLE_LOG_ERROR ]] ;;
|
|
*) false ;;
|
|
esac
|
|
}
|
|
|
|
# Unified logging function
|
|
particle_log() {
|
|
local level="$1"
|
|
local message="$2"
|
|
local script_name="${3:-$(basename "${BASH_SOURCE[1]:-unknown}")}"
|
|
local timestamp
|
|
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
|
|
if should_log "$level"; then
|
|
echo "[$timestamp] [$level] [$script_name] $message" | tee -a "$PARTICLE_MAIN_LOG"
|
|
fi
|
|
}
|
|
|
|
# Convenience logging functions
|
|
log_debug() { particle_log "DEBUG" "$1" "$2"; }
|
|
log_info() { particle_log "INFO" "$1" "$2"; }
|
|
log_warning() { particle_log "WARNING" "$1" "$2"; }
|
|
log_error() { particle_log "ERROR" "$1" "$2"; }
|
|
|
|
# =============================================================================
|
|
# UTILITY FUNCTIONS
|
|
# =============================================================================
|
|
|
|
# Get Ubuntu version
|
|
get_ubuntu_version() {
|
|
lsb_release -rs 2>/dev/null || echo "unknown"
|
|
}
|
|
|
|
# Get Ubuntu codename
|
|
get_ubuntu_codename() {
|
|
lsb_release -cs 2>/dev/null || echo "unknown"
|
|
}
|
|
|
|
# Check if running as root
|
|
check_root() {
|
|
if [[ $EUID -ne 0 ]]; then
|
|
log_error "This operation requires root privileges" "config"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Get system architecture
|
|
get_architecture() {
|
|
uname -m
|
|
}
|
|
|
|
# Check if system supports Secure Boot
|
|
check_secure_boot() {
|
|
if [[ -d "/sys/firmware/efi" ]] && [[ -f "/sys/kernel/security/efi_test" ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# EXPORT CONFIGURATION
|
|
# =============================================================================
|
|
|
|
# Export all configuration variables
|
|
export PARTICLE_ROOT PARTICLE_CONFIG_DIR PARTICLE_LOG_DIR PARTICLE_CACHE_DIR
|
|
export PARTICLE_SCRIPTS_DIR COMPOSEFS_SCRIPT BOOTUPD_SCRIPT APT_LAYER_SCRIPT
|
|
export COMPOSEFS_DIR COMPOSEFS_IMAGES_DIR COMPOSEFS_LAYERS_DIR COMPOSEFS_MOUNTS_DIR
|
|
export PARTICLE_BUILD_DIR PARTICLE_WORKSPACE_DIR PARTICLE_TEMP_DIR
|
|
export PARTICLE_LIVE_OVERLAY_DIR PARTICLE_LIVE_UPPER_DIR PARTICLE_LIVE_WORK_DIR
|
|
export PARTICLE_TRANSACTION_LOG PARTICLE_TRANSACTION_STATE PARTICLE_TRANSACTION_BACKUP_DIR
|
|
export PARTICLE_LOG_LEVEL PARTICLE_MAIN_LOG COMPOSEFS_LOG BOOTUPD_LOG APT_LAYER_LOG
|
|
export PARTICLE_LOG_MAX_SIZE PARTICLE_LOG_MAX_FILES PARTICLE_LOG_COMPRESSION PARTICLE_LOG_FILES_PATTERN
|
|
export PARTICLE_SIGNING_KEY PARTICLE_SIGNING_KEYRING
|
|
export PARTICLE_SECURE_BOOT_ENABLED PARTICLE_SB_KEYS_DIR
|
|
export PARTICLE_PARALLEL_JOBS PARTICLE_MAX_PARALLEL_JOBS
|
|
export PARTICLE_SQUASHFS_COMPRESSION PARTICLE_SQUASHFS_BLOCK_SIZE
|
|
export PARTICLE_APT_CACHE_DIR PARTICLE_CONTAINER_CACHE_DIR
|
|
export PARTICLE_CONTAINER_RUNTIME
|
|
export PARTICLE_REGISTRY_URL PARTICLE_REGISTRY_USERNAME PARTICLE_REGISTRY_PASSWORD
|
|
export PARTICLE_HTTP_PROXY PARTICLE_HTTPS_PROXY PARTICLE_NO_PROXY
|
|
|
|
# Export functions
|
|
export -f validate_particle_config init_particle_environment
|
|
export -f get_log_level should_log particle_log
|
|
export -f log_debug log_info log_warning log_error
|
|
export -f get_ubuntu_version get_ubuntu_codename check_root get_architecture check_secure_boot
|
|
|
|
# =============================================================================
|
|
# AUTO-INITIALIZATION
|
|
# =============================================================================
|
|
|
|
# Auto-initialize if this file is sourced
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
# This file is being executed directly
|
|
echo "Particle-OS Configuration"
|
|
echo "========================="
|
|
echo "Root directory: $PARTICLE_ROOT"
|
|
echo "Config directory: $PARTICLE_CONFIG_DIR"
|
|
echo "Log directory: $PARTICLE_LOG_DIR"
|
|
echo "Log level: $PARTICLE_LOG_LEVEL"
|
|
echo ""
|
|
|
|
if init_particle_environment; then
|
|
echo "Environment initialized successfully"
|
|
else
|
|
echo "Environment initialization failed"
|
|
exit 1
|
|
fi
|
|
else
|
|
# This file is being sourced
|
|
init_particle_environment
|
|
fi |