particle-os-tools/particle-config.sh
robojerk 74c7bede5f Initial commit: Particle-OS tools repository
- 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
2025-07-11 21:14:33 -07:00

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