- 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
2634 lines
78 KiB
Bash
2634 lines
78 KiB
Bash
#!/bin/bash
|
|
|
|
################################################################################################################
|
|
# #
|
|
# WARNING: This file is automatically generated #
|
|
# DO NOT modify this file directly as it will be overwritten #
|
|
# #
|
|
# Ubuntu uBlue bootupd-alternative Tool #
|
|
# Generated on: 2025-07-10 22:47:32 #
|
|
# #
|
|
################################################################################################################
|
|
|
|
set -euo pipefail
|
|
|
|
# Ubuntu uBlue bootupd-alternative Tool - Self-contained version
|
|
# This script contains all components merged into a single file
|
|
# Enhanced bootloader management for Ubuntu uBlue systems
|
|
# Supports multiple bootloader types (GRUB, UEFI, LILO, syslinux)
|
|
|
|
|
|
# Version: 25.07.10
|
|
# Ubuntu uBlue bootupd-alternative Tool
|
|
# Enhanced Bootloader Management
|
|
|
|
|
|
# Source Ubuntu uBlue configuration (if available)
|
|
if [[ -f "/usr/local/etc/particle-config.sh" ]]; then
|
|
source "/usr/local/etc/particle-config.sh"
|
|
log_info "Loaded Ubuntu uBlue configuration" "bootupd-alternative"
|
|
else
|
|
# Define logging functions if not available
|
|
log_info() {
|
|
local message="$1"
|
|
local script_name="${2:-bootupd-alternative}"
|
|
echo "[INFO] [$script_name] $message"
|
|
}
|
|
log_warning() {
|
|
local message="$1"
|
|
local script_name="${2:-bootupd-alternative}"
|
|
echo "[WARNING] [$script_name] $message" >&2
|
|
}
|
|
log_error() {
|
|
local message="$1"
|
|
local script_name="${2:-bootupd-alternative}"
|
|
echo "[ERROR] [$script_name] $message" >&2
|
|
}
|
|
log_debug() {
|
|
local message="$1"
|
|
local script_name="${2:-bootupd-alternative}"
|
|
echo "[DEBUG] [$script_name] $message"
|
|
}
|
|
log_success() {
|
|
local message="$1"
|
|
local script_name="${2:-bootupd-alternative}"
|
|
echo "[SUCCESS] [$script_name] $message"
|
|
}
|
|
log_warning "Ubuntu uBlue configuration not found, using defaults" "bootupd-alternative"
|
|
fi
|
|
|
|
|
|
# ============================================================================
|
|
# Header and Shared Functions
|
|
# ============================================================================
|
|
|
|
|
|
# --- END OF SCRIPTLET: 00-header.sh ---
|
|
|
|
# ============================================================================
|
|
# Dependency Checking and Validation
|
|
# ============================================================================
|
|
# Dependency checking and validation for Ubuntu uBlue bootupd-alternative Tool
|
|
check_dependencies() {
|
|
log_info "Checking dependencies..." "bootupd-alternative"
|
|
|
|
local missing_deps=()
|
|
|
|
# Core dependencies
|
|
for dep in mount umount lsblk bc; do
|
|
if ! command -v "$dep" >/dev/null 2>&1; then
|
|
missing_deps+=("$dep")
|
|
fi
|
|
done
|
|
|
|
# Bootloader-specific dependencies
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
if ! command -v efibootmgr >/dev/null 2>&1; then
|
|
missing_deps+=("efibootmgr")
|
|
fi
|
|
;;
|
|
"grub")
|
|
if ! command -v grub-install >/dev/null 2>&1; then
|
|
missing_deps+=("grub-install")
|
|
fi
|
|
if ! command -v grub-mkconfig >/dev/null 2>&1; then
|
|
missing_deps+=("grub-mkconfig")
|
|
fi
|
|
;;
|
|
"lilo")
|
|
if ! command -v lilo >/dev/null 2>&1; then
|
|
missing_deps+=("lilo")
|
|
fi
|
|
;;
|
|
"syslinux")
|
|
if ! command -v syslinux >/dev/null 2>&1; then
|
|
missing_deps+=("syslinux")
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# Check for kernel modules
|
|
check_kernel_modules
|
|
|
|
if [ ${#missing_deps[@]} -ne 0 ]; then
|
|
log_error "Missing dependencies: ${missing_deps[*]}" "bootupd-alternative"
|
|
log_info "Install missing packages with: sudo apt install -y ${missing_deps[*]}" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "All dependencies found" "bootupd-alternative"
|
|
}
|
|
|
|
# Check kernel modules
|
|
check_kernel_modules() {
|
|
log_info "Checking kernel modules..." "bootupd-alternative"
|
|
|
|
local missing_modules=()
|
|
|
|
# Check for squashfs module
|
|
if ! modprobe -n squashfs >/dev/null 2>&1; then
|
|
missing_modules+=("squashfs")
|
|
fi
|
|
|
|
# Check for overlay module
|
|
if ! modprobe -n overlay >/dev/null 2>&1; then
|
|
missing_modules+=("overlay")
|
|
fi
|
|
|
|
# Check for loop module
|
|
if ! modprobe -n loop >/dev/null 2>&1; then
|
|
missing_modules+=("loop")
|
|
fi
|
|
|
|
if [ ${#missing_modules[@]} -ne 0 ]; then
|
|
log_warning "Missing kernel modules: ${missing_modules[*]}" "bootupd-alternative"
|
|
log_info "Load modules with: sudo modprobe ${missing_modules[*]}" "bootupd-alternative"
|
|
log_info "Or install with: sudo apt install linux-modules-extra-$(uname -r)" "bootupd-alternative"
|
|
else
|
|
log_success "All required kernel modules available" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Check for bootloader integration script
|
|
check_bootloader_integration() {
|
|
local bootloader_script="/usr/local/bin/bootloader-integration.sh"
|
|
|
|
if [[ -f "$bootloader_script" ]] && [[ -x "$bootloader_script" ]]; then
|
|
log_debug "Bootloader integration script found: $bootloader_script" "bootupd-alternative"
|
|
return 0
|
|
else
|
|
log_warning "Bootloader integration script not found or not executable: $bootloader_script" "bootupd-alternative"
|
|
log_info "Advanced bootloader features will not be available" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Check for composefs integration script
|
|
check_composefs_integration() {
|
|
local composefs_script="/usr/local/bin/composefs-alternative.sh"
|
|
|
|
if [[ -f "$composefs_script" ]] && [[ -x "$composefs_script" ]]; then
|
|
log_debug "ComposeFS integration script found: $composefs_script" "bootupd-alternative"
|
|
return 0
|
|
else
|
|
log_warning "ComposeFS integration script not found or not executable: $composefs_script" "bootupd-alternative"
|
|
log_info "ComposeFS-based boot images will not be available" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Validate boot device
|
|
validate_boot_device() {
|
|
local device="$1"
|
|
|
|
# Check if device exists
|
|
if [[ ! -b "$device" ]]; then
|
|
log_error "Boot device does not exist: $device" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if device is readable
|
|
if [[ ! -r "$device" ]]; then
|
|
log_error "Boot device is not readable: $device" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if device has boot partition
|
|
local has_boot_partition=false
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ boot ]] || [[ "$line" =~ efi ]]; then
|
|
has_boot_partition=true
|
|
break
|
|
fi
|
|
done < <(lsblk -o MOUNTPOINT "$device" 2>/dev/null)
|
|
|
|
if [[ "$has_boot_partition" == "false" ]]; then
|
|
log_warning "No boot partition detected on device: $device" "bootupd-alternative"
|
|
log_info "This may be expected for some configurations" "bootupd-alternative"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Check available disk space
|
|
check_disk_space() {
|
|
local required_space_mb="$1"
|
|
local target_dir="${2:-$BOOTUPD_DIR}"
|
|
|
|
local available_space_mb
|
|
available_space_mb=$(get_available_space "$target_dir")
|
|
|
|
if [[ $available_space_mb -lt $required_space_mb ]]; then
|
|
log_error "Insufficient disk space: ${available_space_mb}MB available, need ${required_space_mb}MB" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Disk space check passed: ${available_space_mb}MB available" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Check if system is bootable
|
|
check_system_bootability() {
|
|
log_info "Checking system bootability..." "bootupd-alternative"
|
|
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
# Check for UEFI firmware
|
|
if [[ ! -d "/sys/firmware/efi" ]]; then
|
|
log_error "UEFI firmware not detected" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check for EFI partition
|
|
if ! mountpoint -q /boot/efi 2>/dev/null; then
|
|
log_warning "EFI partition not mounted at /boot/efi" "bootupd-alternative"
|
|
fi
|
|
;;
|
|
"grub")
|
|
# Check for GRUB configuration
|
|
if [[ ! -f "/boot/grub/grub.cfg" ]] && [[ ! -f "/boot/grub2/grub.cfg" ]]; then
|
|
log_warning "GRUB configuration not found" "bootupd-alternative"
|
|
fi
|
|
;;
|
|
"lilo")
|
|
# Check for LILO configuration
|
|
if [[ ! -f "/etc/lilo.conf" ]]; then
|
|
log_warning "LILO configuration not found" "bootupd-alternative"
|
|
fi
|
|
;;
|
|
"syslinux")
|
|
# Check for syslinux configuration
|
|
if [[ ! -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
log_warning "syslinux configuration not found" "bootupd-alternative"
|
|
fi
|
|
;;
|
|
"unknown")
|
|
log_warning "Unknown bootloader type" "bootupd-alternative"
|
|
;;
|
|
esac
|
|
|
|
log_info "System bootability check completed" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Check for required filesystems
|
|
check_filesystems() {
|
|
log_info "Checking required filesystems..." "bootupd-alternative"
|
|
|
|
# Check for /boot
|
|
if [[ ! -d "/boot" ]]; then
|
|
log_error "/boot directory not found" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check for /boot/efi (UEFI systems)
|
|
if [[ -d "/sys/firmware/efi" ]] && [[ ! -d "/boot/efi" ]]; then
|
|
log_warning "EFI directory not found at /boot/efi" "bootupd-alternative"
|
|
fi
|
|
|
|
# Check for /etc/fstab
|
|
if [[ ! -f "/etc/fstab" ]]; then
|
|
log_warning "/etc/fstab not found" "bootupd-alternative"
|
|
fi
|
|
|
|
log_success "Filesystem check completed" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 01-dependencies.sh ---
|
|
|
|
# ============================================================================
|
|
# Bootloader Management
|
|
# ============================================================================
|
|
# Bootloader-specific operations for Ubuntu uBlue bootupd-alternative Tool
|
|
# Provides installation, update, and management for various bootloader types
|
|
|
|
# Install bootloader to device
|
|
install_bootloader() {
|
|
local device="$1"
|
|
|
|
log_info "Installing bootloader to device: $device" "bootupd-alternative"
|
|
|
|
# Validate device
|
|
if ! validate_boot_device "$device"; then
|
|
log_error "Invalid boot device: $device" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Get device information
|
|
log_info "Device information:" "bootupd-alternative"
|
|
get_device_info "$device"
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
install_uefi_bootloader "$device"
|
|
;;
|
|
"grub")
|
|
install_grub_bootloader "$device"
|
|
;;
|
|
"lilo")
|
|
install_lilo_bootloader "$device"
|
|
;;
|
|
"syslinux")
|
|
install_syslinux_bootloader "$device"
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log_success "Bootloader installed successfully to $device" "bootupd-alternative"
|
|
}
|
|
|
|
# Find EFI partition
|
|
find_efi_partition() {
|
|
# Try to find EFI partition using various methods
|
|
local efi_partition=""
|
|
|
|
# Method 1: Check mount point
|
|
if mountpoint -q /boot/efi 2>/dev/null; then
|
|
efi_partition=$(findmnt -n -o SOURCE /boot/efi 2>/dev/null)
|
|
if [[ -n "$efi_partition" ]]; then
|
|
echo "$efi_partition"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Method 2: Look for EFI partition in /proc/mounts
|
|
efi_partition=$(grep " /boot/efi " /proc/mounts | awk '{print $1}')
|
|
if [[ -n "$efi_partition" ]]; then
|
|
echo "$efi_partition"
|
|
return 0
|
|
fi
|
|
|
|
# Method 3: Scan for EFI partition using blkid
|
|
if command -v blkid &> /dev/null; then
|
|
efi_partition=$(blkid | grep -i "EFI" | head -1 | cut -d: -f1)
|
|
if [[ -n "$efi_partition" ]]; then
|
|
echo "$efi_partition"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Method 4: Look for common EFI partition names
|
|
for dev in /dev/sd*1 /dev/nvme*n*p1 /dev/mmcblk*p1; do
|
|
if [[ -b "$dev" ]]; then
|
|
efi_partition="$dev"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ -n "$efi_partition" ]]; then
|
|
echo "$efi_partition"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# Install UEFI bootloader
|
|
install_uefi_bootloader() {
|
|
local device="$1"
|
|
|
|
log_info "Installing UEFI bootloader..." "bootupd-alternative"
|
|
|
|
# Check if EFI partition is mounted
|
|
if ! mountpoint -q /boot/efi 2>/dev/null; then
|
|
log_error "EFI partition not mounted at /boot/efi" "bootupd-alternative"
|
|
log_info "Please mount the EFI partition before installing UEFI bootloader" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Create EFI boot entry
|
|
if command -v efibootmgr &> /dev/null; then
|
|
log_info "Creating EFI boot entry..." "bootupd-alternative"
|
|
|
|
# Find EFI partition
|
|
local efi_partition
|
|
efi_partition=$(find_efi_partition)
|
|
if [[ -z "$efi_partition" ]]; then
|
|
log_error "Could not find EFI partition" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Extract device and partition number
|
|
local efi_device
|
|
local efi_part_num
|
|
efi_device=$(echo "$efi_partition" | sed 's/[0-9]*$//')
|
|
efi_part_num=$(echo "$efi_partition" | sed 's/.*\([0-9]*\)$/\1/')
|
|
|
|
# Determine EFI loader path
|
|
local efi_loader="/EFI/ubuntu/grubx64.efi"
|
|
if [[ ! -f "/boot/efi$efi_loader" ]]; then
|
|
# Try alternative paths
|
|
for alt_loader in "/EFI/ubuntu/shimx64.efi" "/EFI/boot/bootx64.efi" "/EFI/BOOT/BOOTX64.EFI"; do
|
|
if [[ -f "/boot/efi$alt_loader" ]]; then
|
|
efi_loader="$alt_loader"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Create EFI boot entry
|
|
if efibootmgr --create --disk "$efi_device" --part "$efi_part_num" --loader "$efi_loader" --label "Ubuntu uBlue" --unicode "quiet splash"; then
|
|
log_success "EFI boot entry created: Ubuntu uBlue" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to create EFI boot entry" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_warning "efibootmgr not available, skipping EFI boot entry creation" "bootupd-alternative"
|
|
fi
|
|
|
|
log_success "UEFI bootloader installation completed" "bootupd-alternative"
|
|
}
|
|
|
|
# Install GRUB bootloader
|
|
install_grub_bootloader() {
|
|
local device="$1"
|
|
|
|
log_info "Installing GRUB bootloader..." "bootupd-alternative"
|
|
|
|
# Check for GRUB installation tools
|
|
if ! command -v grub-install &> /dev/null; then
|
|
log_error "grub-install not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Install GRUB to device
|
|
if grub-install "$device"; then
|
|
log_success "GRUB installed to $device" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to install GRUB to $device" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Generate GRUB configuration
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Generating GRUB configuration..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration generated" "bootupd-alternative"
|
|
else
|
|
log_warning "Failed to generate GRUB configuration" "bootupd-alternative"
|
|
fi
|
|
else
|
|
log_warning "grub-mkconfig not found, skipping configuration generation" "bootupd-alternative"
|
|
fi
|
|
|
|
log_success "GRUB bootloader installation completed" "bootupd-alternative"
|
|
}
|
|
|
|
# Install LILO bootloader
|
|
install_lilo_bootloader() {
|
|
local device="$1"
|
|
|
|
log_info "Installing LILO bootloader..." "bootupd-alternative"
|
|
|
|
# Check for LILO
|
|
if ! command -v lilo &> /dev/null; then
|
|
log_error "lilo not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Check for LILO configuration
|
|
if [[ ! -f "/etc/lilo.conf" ]]; then
|
|
log_error "LILO configuration not found at /etc/lilo.conf" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Install LILO
|
|
if lilo; then
|
|
log_success "LILO installed successfully" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to install LILO" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "LILO bootloader installation completed" "bootupd-alternative"
|
|
}
|
|
|
|
# Install syslinux bootloader
|
|
install_syslinux_bootloader() {
|
|
local device="$1"
|
|
|
|
log_info "Installing syslinux bootloader..." "bootupd-alternative"
|
|
|
|
# Check for syslinux
|
|
if ! command -v syslinux &> /dev/null; then
|
|
log_error "syslinux not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Install syslinux (try different methods)
|
|
local install_success=false
|
|
|
|
# Method 1: Direct syslinux installation
|
|
if syslinux -i "$device" 2>/dev/null; then
|
|
install_success=true
|
|
# Method 2: extlinux installation (for ext filesystems)
|
|
elif command -v extlinux &> /dev/null && extlinux --install /boot/syslinux 2>/dev/null; then
|
|
install_success=true
|
|
# Method 3: syslinux with different options
|
|
elif syslinux "$device" 2>/dev/null; then
|
|
install_success=true
|
|
fi
|
|
|
|
if [[ "$install_success" == "true" ]]; then
|
|
log_success "syslinux installed to $device" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to install syslinux to $device" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "syslinux bootloader installation completed" "bootupd-alternative"
|
|
}
|
|
|
|
# Update bootloader configuration
|
|
update_bootloader() {
|
|
log_info "Updating bootloader configuration..." "bootupd-alternative"
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
update_uefi_bootloader
|
|
;;
|
|
"grub")
|
|
update_grub_bootloader
|
|
;;
|
|
"lilo")
|
|
update_lilo_bootloader
|
|
;;
|
|
"syslinux")
|
|
update_syslinux_bootloader
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log_success "Bootloader configuration updated successfully" "bootupd-alternative"
|
|
}
|
|
|
|
# Update UEFI bootloader
|
|
update_uefi_bootloader() {
|
|
log_info "Updating UEFI bootloader..." "bootupd-alternative"
|
|
|
|
# Update EFI boot entries
|
|
if command -v efibootmgr &> /dev/null; then
|
|
log_info "Updating EFI boot entries..." "bootupd-alternative"
|
|
# Implementation would update EFI boot entries here
|
|
log_success "EFI boot entries updated" "bootupd-alternative"
|
|
else
|
|
log_warning "efibootmgr not available, skipping EFI boot entry updates" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Update GRUB bootloader
|
|
update_grub_bootloader() {
|
|
log_info "Updating GRUB bootloader..." "bootupd-alternative"
|
|
|
|
# Update GRUB configuration
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Updating GRUB configuration..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update GRUB configuration" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "grub-mkconfig not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Update LILO bootloader
|
|
update_lilo_bootloader() {
|
|
log_info "Updating LILO bootloader..." "bootupd-alternative"
|
|
|
|
# Update LILO
|
|
if command -v lilo &> /dev/null; then
|
|
if lilo; then
|
|
log_success "LILO updated successfully" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update LILO" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "lilo not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Update syslinux bootloader
|
|
update_syslinux_bootloader() {
|
|
log_info "Updating syslinux bootloader..." "bootupd-alternative"
|
|
|
|
# Update syslinux configuration
|
|
if command -v syslinux &> /dev/null; then
|
|
log_info "Updating syslinux configuration..." "bootupd-alternative"
|
|
|
|
# Regenerate syslinux configuration if possible
|
|
if [[ -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
# Backup current configuration
|
|
cp "/boot/syslinux/syslinux.cfg" "/boot/syslinux/syslinux.cfg.backup"
|
|
|
|
# Try to regenerate configuration
|
|
if command -v extlinux &> /dev/null; then
|
|
if extlinux --update /boot/syslinux; then
|
|
log_success "syslinux configuration updated via extlinux" "bootupd-alternative"
|
|
else
|
|
log_warning "extlinux update failed, using backup" "bootupd-alternative"
|
|
cp "/boot/syslinux/syslinux.cfg.backup" "/boot/syslinux/syslinux.cfg"
|
|
fi
|
|
else
|
|
log_success "syslinux configuration file updated" "bootupd-alternative"
|
|
fi
|
|
else
|
|
log_warning "syslinux configuration not found" "bootupd-alternative"
|
|
fi
|
|
else
|
|
log_error "syslinux not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 02-bootloader.sh ---
|
|
|
|
# ============================================================================
|
|
# Backup and Restore Operations
|
|
# ============================================================================
|
|
# Backup and restore functionality for Ubuntu uBlue bootupd-alternative Tool
|
|
# Provides comprehensive backup and restore of bootloader configurations
|
|
|
|
# Create backup of bootloader configuration
|
|
create_backup() {
|
|
local backup_name="$1"
|
|
local backup_dir="$BOOTUPD_DIR/backups/$backup_name"
|
|
|
|
log_info "Creating backup: $backup_name" "bootupd-alternative"
|
|
|
|
mkdir -p "$backup_dir"
|
|
|
|
# Backup GRUB configuration
|
|
if [[ -f "/boot/grub/grub.cfg" ]]; then
|
|
cp "/boot/grub/grub.cfg" "$backup_dir/grub.cfg"
|
|
log_debug "Backed up GRUB configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
if [[ -d "/etc/grub.d" ]]; then
|
|
cp -r "/etc/grub.d" "$backup_dir/grub.d"
|
|
log_debug "Backed up GRUB.d scripts" "bootupd-alternative"
|
|
fi
|
|
|
|
if [[ -f "/etc/default/grub" ]]; then
|
|
cp "/etc/default/grub" "$backup_dir/grub"
|
|
log_debug "Backed up GRUB defaults" "bootupd-alternative"
|
|
fi
|
|
|
|
# Backup UEFI entries
|
|
if command -v efibootmgr &> /dev/null; then
|
|
if efibootmgr --verbose > "$backup_dir/efi_entries.txt" 2>/dev/null; then
|
|
log_debug "Backed up EFI boot entries" "bootupd-alternative"
|
|
else
|
|
log_warning "Failed to backup EFI boot entries" "bootupd-alternative"
|
|
fi
|
|
else
|
|
log_warning "efibootmgr not available, skipping EFI entries backup" "bootupd-alternative"
|
|
fi
|
|
|
|
# Backup LILO configuration
|
|
if [[ -f "/etc/lilo.conf" ]]; then
|
|
cp "/etc/lilo.conf" "$backup_dir/lilo.conf"
|
|
log_debug "Backed up LILO configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
# Backup syslinux configuration
|
|
if [[ -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
cp "/boot/syslinux/syslinux.cfg" "$backup_dir/syslinux.cfg"
|
|
log_debug "Backed up syslinux configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
# Create backup metadata
|
|
cat > "$backup_dir/backup_info.txt" << EOF
|
|
Backup created: $(date)
|
|
Backup name: $backup_name
|
|
Bootloader type: $(detect_bootloader)
|
|
Kernel version: $(uname -r)
|
|
Architecture: $(uname -m)
|
|
EOF
|
|
|
|
log_success "Backup created: $backup_dir" "bootupd-alternative"
|
|
echo "$backup_dir"
|
|
}
|
|
|
|
# Restore backup of bootloader configuration
|
|
restore_backup() {
|
|
local backup_name="$1"
|
|
local backup_dir="$BOOTUPD_DIR/backups/$backup_name"
|
|
|
|
if [[ ! -d "$backup_dir" ]]; then
|
|
log_error "Backup not found: $backup_name" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Restoring backup: $backup_name" "bootupd-alternative"
|
|
|
|
# Restore GRUB configuration
|
|
if [[ -f "$backup_dir/grub.cfg" ]]; then
|
|
cp "$backup_dir/grub.cfg" "/boot/grub/grub.cfg"
|
|
log_debug "Restored GRUB configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
if [[ -d "$backup_dir/grub.d" ]]; then
|
|
cp -r "$backup_dir/grub.d" /etc/
|
|
log_debug "Restored GRUB.d scripts" "bootupd-alternative"
|
|
fi
|
|
|
|
if [[ -f "$backup_dir/grub" ]]; then
|
|
cp "$backup_dir/grub" "/etc/default/grub"
|
|
log_debug "Restored GRUB defaults" "bootupd-alternative"
|
|
fi
|
|
|
|
# Update GRUB configuration after restore
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Updating GRUB configuration after restore..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration updated" "bootupd-alternative"
|
|
else
|
|
log_warning "Failed to update GRUB configuration" "bootupd-alternative"
|
|
fi
|
|
fi
|
|
|
|
# Restore LILO configuration
|
|
if [[ -f "$backup_dir/lilo.conf" ]]; then
|
|
cp "$backup_dir/lilo.conf" "/etc/lilo.conf"
|
|
log_debug "Restored LILO configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
# Restore syslinux configuration
|
|
if [[ -f "$backup_dir/syslinux.cfg" ]]; then
|
|
cp "$backup_dir/syslinux.cfg" "/boot/syslinux/syslinux.cfg"
|
|
log_debug "Restored syslinux configuration" "bootupd-alternative"
|
|
fi
|
|
|
|
log_success "Backup restored: $backup_name" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# List available backups
|
|
list_backups() {
|
|
log_info "Available backups:" "bootupd-alternative"
|
|
|
|
if [[ ! -d "$BOOTUPD_DIR/backups" ]]; then
|
|
log_info "No backups found" "bootupd-alternative"
|
|
return 0
|
|
fi
|
|
|
|
local backup_count=0
|
|
for backup_dir in "$BOOTUPD_DIR/backups"/*; do
|
|
if [[ -d "$backup_dir" ]]; then
|
|
local backup_name
|
|
backup_name=$(basename "$backup_dir")
|
|
local backup_date
|
|
backup_date=$(stat -c %y "$backup_dir" | cut -d' ' -f1)
|
|
echo " $backup_name (created: $backup_date)"
|
|
backup_count=$((backup_count + 1))
|
|
fi
|
|
done
|
|
|
|
if [[ $backup_count -eq 0 ]]; then
|
|
log_info "No backups found" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Validate backup integrity
|
|
validate_backup() {
|
|
local backup_name="$1"
|
|
local backup_dir="$BOOTUPD_DIR/backups/$backup_name"
|
|
|
|
if [[ ! -d "$backup_dir" ]]; then
|
|
log_error "Backup not found: $backup_name" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Validating backup: $backup_name" "bootupd-alternative"
|
|
|
|
local validation_errors=0
|
|
|
|
# Check for backup metadata
|
|
if [[ ! -f "$backup_dir/backup_info.txt" ]]; then
|
|
log_warning "Backup metadata not found" "bootupd-alternative"
|
|
validation_errors=$((validation_errors + 1))
|
|
fi
|
|
|
|
# Check for at least one configuration file
|
|
local has_config=false
|
|
for config_file in grub.cfg lilo.conf syslinux.cfg; do
|
|
if [[ -f "$backup_dir/$config_file" ]]; then
|
|
has_config=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ "$has_config" == "false" ]]; then
|
|
log_warning "No configuration files found in backup" "bootupd-alternative"
|
|
validation_errors=$((validation_errors + 1))
|
|
fi
|
|
|
|
if [[ $validation_errors -eq 0 ]]; then
|
|
log_success "Backup validation passed" "bootupd-alternative"
|
|
return 0
|
|
else
|
|
log_warning "Backup validation completed with $validation_errors warnings" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Remove backup
|
|
remove_backup() {
|
|
local backup_name="$1"
|
|
local backup_dir="$BOOTUPD_DIR/backups/$backup_name"
|
|
|
|
if [[ ! -d "$backup_dir" ]]; then
|
|
log_error "Backup not found: $backup_name" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Removing backup: $backup_name" "bootupd-alternative"
|
|
|
|
if rm -rf "$backup_dir"; then
|
|
log_success "Backup removed: $backup_name" "bootupd-alternative"
|
|
return 0
|
|
else
|
|
log_error "Failed to remove backup: $backup_name" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 03-backup.sh ---
|
|
|
|
# ============================================================================
|
|
# Boot Entry Management
|
|
# ============================================================================
|
|
# Boot entries management for Ubuntu uBlue bootupd-alternative Tool
|
|
# Provides management of boot entries for various bootloader types
|
|
|
|
# Convert device path to GRUB format
|
|
convert_device_to_grub_format() {
|
|
local device="$1"
|
|
|
|
if [[ -z "$device" ]]; then
|
|
echo "hd0,msdos1" # Default fallback
|
|
return 0
|
|
fi
|
|
|
|
# Extract device name and partition
|
|
local device_name
|
|
local partition_num
|
|
device_name=$(echo "$device" | sed 's/[0-9]*$//')
|
|
partition_num=$(echo "$device" | sed 's/.*\([0-9]*\)$/\1/')
|
|
|
|
# Determine disk number (simplified - assumes first disk)
|
|
local disk_num=0
|
|
|
|
# Determine partition table type
|
|
local partition_table="msdos"
|
|
if command -v parted &> /dev/null; then
|
|
if parted "$device_name" print 2>/dev/null | grep -q "gpt"; then
|
|
partition_table="gpt"
|
|
fi
|
|
fi
|
|
|
|
# Convert to GRUB format
|
|
if [[ "$partition_table" == "gpt" ]]; then
|
|
echo "hd${disk_num},gpt${partition_num}"
|
|
else
|
|
echo "hd${disk_num},msdos${partition_num}"
|
|
fi
|
|
}
|
|
|
|
# Add boot entry
|
|
add_boot_entry() {
|
|
local title="$1"
|
|
local kernel_path="$2"
|
|
local initrd_path="$3"
|
|
local root_device="$4"
|
|
|
|
log_info "Adding boot entry: $title" "bootupd-alternative"
|
|
|
|
# Validate inputs
|
|
if ! validate_boot_title "$title"; then
|
|
log_error "Invalid boot title: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$kernel_path" ]]; then
|
|
log_error "Kernel not found: $kernel_path" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -n "$initrd_path" && ! -f "$initrd_path" ]]; then
|
|
log_error "Initrd not found: $initrd_path" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
add_uefi_boot_entry "$title" "$kernel_path" "$initrd_path" "$root_device"
|
|
;;
|
|
"grub")
|
|
add_grub_boot_entry "$title" "$kernel_path" "$initrd_path" "$root_device"
|
|
;;
|
|
"lilo")
|
|
add_lilo_boot_entry "$title" "$kernel_path" "$initrd_path" "$root_device"
|
|
;;
|
|
"syslinux")
|
|
add_syslinux_boot_entry "$title" "$kernel_path" "$initrd_path" "$root_device"
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log_success "Boot entry added: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Add UEFI boot entry
|
|
add_uefi_boot_entry() {
|
|
local title="$1"
|
|
local kernel_path="$2"
|
|
local initrd_path="$3"
|
|
local root_device="$4"
|
|
|
|
log_info "Adding UEFI boot entry..." "bootupd-alternative"
|
|
|
|
if ! command -v efibootmgr &> /dev/null; then
|
|
log_error "efibootmgr not available" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Find EFI partition
|
|
local efi_partition
|
|
efi_partition=$(find_efi_partition)
|
|
if [[ -z "$efi_partition" ]]; then
|
|
log_error "Could not find EFI partition" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Extract device and partition number
|
|
local efi_device
|
|
local efi_part_num
|
|
efi_device=$(echo "$efi_partition" | sed 's/[0-9]*$//')
|
|
efi_part_num=$(echo "$efi_partition" | sed 's/.*\([0-9]*\)$/\1/')
|
|
|
|
# Determine EFI loader path
|
|
local efi_loader="/EFI/ubuntu/grubx64.efi"
|
|
if [[ ! -f "/boot/efi$efi_loader" ]]; then
|
|
# Try alternative paths
|
|
for alt_loader in "/EFI/ubuntu/shimx64.efi" "/EFI/boot/bootx64.efi" "/EFI/BOOT/BOOTX64.EFI"; do
|
|
if [[ -f "/boot/efi$alt_loader" ]]; then
|
|
efi_loader="$alt_loader"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Build kernel arguments
|
|
local efi_args=""
|
|
if [[ -n "$initrd_path" ]]; then
|
|
efi_args="initrd=$initrd_path"
|
|
fi
|
|
if [[ -n "$root_device" ]]; then
|
|
if [[ -n "$efi_args" ]]; then
|
|
efi_args="$efi_args root=$root_device"
|
|
else
|
|
efi_args="root=$root_device"
|
|
fi
|
|
fi
|
|
|
|
# Create EFI boot entry
|
|
if efibootmgr --create --disk "$efi_device" --part "$efi_part_num" --loader "$efi_loader" --label "$title" --unicode "$efi_args"; then
|
|
log_success "UEFI boot entry added: $title" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to create UEFI boot entry: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Add GRUB boot entry
|
|
add_grub_boot_entry() {
|
|
local title="$1"
|
|
local kernel_path="$2"
|
|
local initrd_path="$3"
|
|
local root_device="$4"
|
|
|
|
log_info "Adding GRUB boot entry..." "bootupd-alternative"
|
|
|
|
# Create GRUB configuration entry
|
|
local grub_entry="/etc/grub.d/40_custom"
|
|
|
|
# Convert device path to GRUB format
|
|
local grub_root
|
|
grub_root=$(convert_device_to_grub_format "$root_device")
|
|
|
|
# Add entry to custom GRUB configuration
|
|
cat >> "$grub_entry" << EOF
|
|
|
|
# Custom entry: $title
|
|
menuentry '$title' {
|
|
set root='$grub_root'
|
|
linux $kernel_path root=$root_device ro
|
|
EOF
|
|
|
|
if [[ -n "$initrd_path" ]]; then
|
|
echo " initrd $initrd_path" >> "$grub_entry"
|
|
fi
|
|
|
|
echo "}" >> "$grub_entry"
|
|
|
|
# Update GRUB configuration
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Updating GRUB configuration..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update GRUB configuration" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_warning "grub-mkconfig not found, manual update required" "bootupd-alternative"
|
|
fi
|
|
|
|
log_success "GRUB boot entry added: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Add LILO boot entry
|
|
add_lilo_boot_entry() {
|
|
local title="$1"
|
|
local kernel_path="$2"
|
|
local initrd_path="$3"
|
|
local root_device="$4"
|
|
|
|
log_info "Adding LILO boot entry..." "bootupd-alternative"
|
|
|
|
# Add entry to LILO configuration
|
|
local lilo_conf="/etc/lilo.conf"
|
|
|
|
if [[ ! -f "$lilo_conf" ]]; then
|
|
log_error "LILO configuration not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Create backup before modification
|
|
cp "$lilo_conf" "$lilo_conf.backup"
|
|
|
|
# Add entry to LILO configuration
|
|
cat >> "$lilo_conf" << EOF
|
|
|
|
# Custom entry: $title
|
|
image=$kernel_path
|
|
label=$title
|
|
root=$root_device
|
|
read-only
|
|
EOF
|
|
|
|
if [[ -n "$initrd_path" ]]; then
|
|
echo " initrd=$initrd_path" >> "$lilo_conf"
|
|
fi
|
|
|
|
# Update LILO
|
|
if command -v lilo &> /dev/null; then
|
|
log_info "Updating LILO..." "bootupd-alternative"
|
|
if lilo; then
|
|
log_success "LILO updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update LILO" "bootupd-alternative"
|
|
# Restore backup
|
|
cp "$lilo_conf.backup" "$lilo_conf"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "lilo not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "LILO boot entry added: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Add syslinux boot entry
|
|
add_syslinux_boot_entry() {
|
|
local title="$1"
|
|
local kernel_path="$2"
|
|
local initrd_path="$3"
|
|
local root_device="$4"
|
|
|
|
log_info "Adding syslinux boot entry..." "bootupd-alternative"
|
|
|
|
# Add entry to syslinux configuration
|
|
local syslinux_cfg="/boot/syslinux/syslinux.cfg"
|
|
|
|
if [[ ! -f "$syslinux_cfg" ]]; then
|
|
log_error "syslinux configuration not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Create backup before modification
|
|
cp "$syslinux_cfg" "$syslinux_cfg.backup"
|
|
|
|
# Add entry to syslinux configuration
|
|
cat >> "$syslinux_cfg" << EOF
|
|
|
|
# Custom entry: $title
|
|
LABEL $title
|
|
KERNEL $kernel_path
|
|
APPEND root=$root_device ro
|
|
EOF
|
|
|
|
if [[ -n "$initrd_path" ]]; then
|
|
echo " INITRD $initrd_path" >> "$syslinux_cfg"
|
|
fi
|
|
|
|
log_success "syslinux boot entry added: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Remove boot entry
|
|
remove_boot_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Removing boot entry: $title" "bootupd-alternative"
|
|
|
|
# Validate title
|
|
if ! validate_boot_title "$title"; then
|
|
log_error "Invalid boot title: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
remove_uefi_boot_entry "$title"
|
|
;;
|
|
"grub")
|
|
remove_grub_boot_entry "$title"
|
|
;;
|
|
"lilo")
|
|
remove_lilo_boot_entry "$title"
|
|
;;
|
|
"syslinux")
|
|
remove_syslinux_boot_entry "$title"
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log_success "Boot entry removed: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Remove UEFI boot entry
|
|
remove_uefi_boot_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Removing UEFI boot entry..." "bootupd-alternative"
|
|
|
|
if ! command -v efibootmgr &> /dev/null; then
|
|
log_error "efibootmgr not available" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Find boot number for the given title
|
|
local boot_num
|
|
boot_num=$(efibootmgr --verbose 2>/dev/null | grep -i "$title" | head -1 | sed -n 's/^Boot\([0-9a-fA-F]*\).*/\1/p')
|
|
|
|
if [[ -z "$boot_num" ]]; then
|
|
log_error "UEFI boot entry not found: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Remove the boot entry
|
|
if efibootmgr --delete-bootnum --bootnum "$boot_num"; then
|
|
log_success "UEFI boot entry removed: $title (Boot$boot_num)" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to remove UEFI boot entry: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Remove GRUB boot entry
|
|
remove_grub_boot_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Removing GRUB boot entry..." "bootupd-alternative"
|
|
|
|
# Remove entry from custom GRUB configuration
|
|
local grub_entry="/etc/grub.d/40_custom"
|
|
|
|
if [[ -f "$grub_entry" ]]; then
|
|
# Create backup
|
|
cp "$grub_entry" "$grub_entry.backup"
|
|
|
|
# Remove the entry (simplified - in practice would need more sophisticated parsing)
|
|
sed -i "/# Custom entry: $title/,/^}/d" "$grub_entry"
|
|
|
|
# Update GRUB configuration
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Updating GRUB configuration..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update GRUB configuration" "bootupd-alternative"
|
|
# Restore backup
|
|
cp "$grub_entry.backup" "$grub_entry"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_warning "grub-mkconfig not found, manual update required" "bootupd-alternative"
|
|
fi
|
|
fi
|
|
|
|
log_success "GRUB boot entry removed: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Remove LILO boot entry
|
|
remove_lilo_boot_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Removing LILO boot entry..." "bootupd-alternative"
|
|
|
|
local lilo_conf="/etc/lilo.conf"
|
|
|
|
if [[ -f "$lilo_conf" ]]; then
|
|
# Create backup
|
|
cp "$lilo_conf" "$lilo_conf.backup"
|
|
|
|
# Remove the entry (simplified - in practice would need more sophisticated parsing)
|
|
sed -i "/# Custom entry: $title/,/^$/d" "$lilo_conf"
|
|
|
|
# Update LILO
|
|
if command -v lilo &> /dev/null; then
|
|
log_info "Updating LILO..." "bootupd-alternative"
|
|
if lilo; then
|
|
log_success "LILO updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update LILO" "bootupd-alternative"
|
|
# Restore backup
|
|
cp "$lilo_conf.backup" "$lilo_conf"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "lilo not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
log_success "LILO boot entry removed: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Remove syslinux boot entry
|
|
remove_syslinux_boot_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Removing syslinux boot entry..." "bootupd-alternative"
|
|
|
|
local syslinux_cfg="/boot/syslinux/syslinux.cfg"
|
|
|
|
if [[ -f "$syslinux_cfg" ]]; then
|
|
# Create backup
|
|
cp "$syslinux_cfg" "$syslinux_cfg.backup"
|
|
|
|
# Remove the entry (simplified - in practice would need more sophisticated parsing)
|
|
sed -i "/# Custom entry: $title/,/^$/d" "$syslinux_cfg"
|
|
fi
|
|
|
|
log_success "syslinux boot entry removed: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# List boot entries
|
|
list_boot_entries() {
|
|
log_info "Listing boot entries..." "bootupd-alternative"
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
list_uefi_boot_entries
|
|
;;
|
|
"grub")
|
|
list_grub_boot_entries
|
|
;;
|
|
"lilo")
|
|
list_lilo_boot_entries
|
|
;;
|
|
"syslinux")
|
|
list_syslinux_boot_entries
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# List UEFI boot entries
|
|
list_uefi_boot_entries() {
|
|
log_info "UEFI boot entries:" "bootupd-alternative"
|
|
|
|
if command -v efibootmgr &> /dev/null; then
|
|
efibootmgr --verbose
|
|
else
|
|
log_warning "efibootmgr not available" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# List GRUB boot entries
|
|
list_grub_boot_entries() {
|
|
log_info "GRUB boot entries:" "bootupd-alternative"
|
|
|
|
if [[ -f "/boot/grub/grub.cfg" ]]; then
|
|
grep -E "^[[:space:]]*menuentry" /boot/grub/grub.cfg | sed 's/^[[:space:]]*menuentry[[:space:]]*'\''\([^'\'']*\)'\''.*/\1/'
|
|
else
|
|
log_warning "GRUB configuration not found" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# List LILO boot entries
|
|
list_lilo_boot_entries() {
|
|
log_info "LILO boot entries:" "bootupd-alternative"
|
|
|
|
if [[ -f "/etc/lilo.conf" ]]; then
|
|
grep -E "^[[:space:]]*label" /etc/lilo.conf | sed 's/^[[:space:]]*label[[:space:]]*\([^[:space:]]*\).*/\1/'
|
|
else
|
|
log_warning "LILO configuration not found" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# List syslinux boot entries
|
|
list_syslinux_boot_entries() {
|
|
log_info "syslinux boot entries:" "bootupd-alternative"
|
|
|
|
if [[ -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
grep -E "^[[:space:]]*LABEL" /boot/syslinux/syslinux.cfg | sed 's/^[[:space:]]*LABEL[[:space:]]*\([^[:space:]]*\).*/\1/'
|
|
else
|
|
log_warning "syslinux configuration not found" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Set default boot entry
|
|
set_default_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Setting default boot entry: $title" "bootupd-alternative"
|
|
|
|
# Validate title
|
|
if ! validate_boot_title "$title"; then
|
|
log_error "Invalid boot title: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
set_uefi_default_entry "$title"
|
|
;;
|
|
"grub")
|
|
set_grub_default_entry "$title"
|
|
;;
|
|
"lilo")
|
|
set_lilo_default_entry "$title"
|
|
;;
|
|
"syslinux")
|
|
set_syslinux_default_entry "$title"
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
log_success "Default boot entry set: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Set UEFI default entry
|
|
set_uefi_default_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Setting UEFI default entry..." "bootupd-alternative"
|
|
|
|
if ! command -v efibootmgr &> /dev/null; then
|
|
log_error "efibootmgr not available" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Find boot number for the given title
|
|
local boot_num
|
|
boot_num=$(efibootmgr --verbose 2>/dev/null | grep -i "$title" | head -1 | sed -n 's/^Boot\([0-9a-fA-F]*\).*/\1/p')
|
|
|
|
if [[ -z "$boot_num" ]]; then
|
|
log_error "UEFI boot entry not found: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Set as next boot entry (for one-time boot)
|
|
if efibootmgr --bootnext "$boot_num"; then
|
|
log_success "UEFI next boot entry set: $title (Boot$boot_num)" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to set UEFI next boot entry: $title" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
# Also set as default boot order (persistent)
|
|
local current_order
|
|
current_order=$(efibootmgr 2>/dev/null | grep "BootOrder" | cut -d' ' -f2)
|
|
if [[ -n "$current_order" ]]; then
|
|
local new_order="$boot_num,$current_order"
|
|
if efibootmgr --bootorder "$new_order"; then
|
|
log_success "UEFI boot order updated: $title (Boot$boot_num) is now first" "bootupd-alternative"
|
|
else
|
|
log_warning "Failed to update UEFI boot order, but next boot is set" "bootupd-alternative"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Set GRUB default entry
|
|
set_grub_default_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Setting GRUB default entry..." "bootupd-alternative"
|
|
|
|
local grub_default="/etc/default/grub"
|
|
|
|
if [[ -f "$grub_default" ]]; then
|
|
# Create backup
|
|
cp "$grub_default" "$grub_default.backup"
|
|
|
|
# Set default entry
|
|
sed -i "s/^GRUB_DEFAULT=.*/GRUB_DEFAULT=\"$title\"/" "$grub_default"
|
|
|
|
# Update GRUB configuration
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
log_info "Updating GRUB configuration..." "bootupd-alternative"
|
|
if grub-mkconfig -o /boot/grub/grub.cfg; then
|
|
log_success "GRUB configuration updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update GRUB configuration" "bootupd-alternative"
|
|
# Restore backup
|
|
cp "$grub_default.backup" "$grub_default"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_warning "grub-mkconfig not found, manual update required" "bootupd-alternative"
|
|
fi
|
|
else
|
|
log_error "GRUB defaults file not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "GRUB default entry set: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Set LILO default entry
|
|
set_lilo_default_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Setting LILO default entry..." "bootupd-alternative"
|
|
|
|
local lilo_conf="/etc/lilo.conf"
|
|
|
|
if [[ -f "$lilo_conf" ]]; then
|
|
# Create backup
|
|
cp "$lilo_conf" "$lilo_conf.backup"
|
|
|
|
# Set default entry
|
|
sed -i "s/^default=.*/default=$title/" "$lilo_conf"
|
|
|
|
# Update LILO
|
|
if command -v lilo &> /dev/null; then
|
|
log_info "Updating LILO..." "bootupd-alternative"
|
|
if lilo; then
|
|
log_success "LILO updated" "bootupd-alternative"
|
|
else
|
|
log_error "Failed to update LILO" "bootupd-alternative"
|
|
# Restore backup
|
|
cp "$lilo_conf.backup" "$lilo_conf"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "lilo not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
else
|
|
log_error "LILO configuration not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "LILO default entry set: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# Set syslinux default entry
|
|
set_syslinux_default_entry() {
|
|
local title="$1"
|
|
|
|
log_info "Setting syslinux default entry..." "bootupd-alternative"
|
|
|
|
local syslinux_cfg="/boot/syslinux/syslinux.cfg"
|
|
|
|
if [[ -f "$syslinux_cfg" ]]; then
|
|
# Create backup
|
|
cp "$syslinux_cfg" "$syslinux_cfg.backup"
|
|
|
|
# Set default entry
|
|
sed -i "s/^DEFAULT[[:space:]].*/DEFAULT $title/" "$syslinux_cfg"
|
|
else
|
|
log_error "syslinux configuration not found" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "syslinux default entry set: $title" "bootupd-alternative"
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 04-entries.sh ---
|
|
|
|
# ============================================================================
|
|
# Device Management and Information
|
|
# ============================================================================
|
|
# Device management for Ubuntu uBlue bootupd-alternative Tool
|
|
# Provides device validation, information, and management functions
|
|
|
|
# Validate boot device
|
|
validate_boot_device() {
|
|
local device="$1"
|
|
|
|
if [[ -z "$device" ]]; then
|
|
log_error "Device path is required" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if device exists
|
|
if [[ ! -b "$device" ]]; then
|
|
log_error "Device not found: $device" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if device is readable
|
|
if [[ ! -r "$device" ]]; then
|
|
log_error "Device not readable: $device" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if device is a block device
|
|
if ! stat -c "%t" "$device" &> /dev/null; then
|
|
log_error "Invalid block device: $device" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Device validation passed: $device" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Get device information
|
|
get_device_info() {
|
|
local device="$1"
|
|
|
|
if [[ -z "$device" ]]; then
|
|
log_error "Device path is required" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Device Information for: $device" "bootupd-alternative"
|
|
|
|
# Device size
|
|
if command -v blockdev &> /dev/null; then
|
|
local size_bytes
|
|
size_bytes=$(blockdev --getsize64 "$device" 2>/dev/null)
|
|
if [[ -n "$size_bytes" ]]; then
|
|
local size_gb
|
|
size_gb=$(echo "scale=2; $size_bytes / 1024 / 1024 / 1024" | bc 2>/dev/null || echo "unknown")
|
|
echo " Size: ${size_gb} GB"
|
|
fi
|
|
fi
|
|
|
|
# Device type
|
|
local device_type
|
|
device_type=$(stat -c "%t" "$device" 2>/dev/null)
|
|
if [[ -n "$device_type" ]]; then
|
|
echo " Type: $device_type"
|
|
fi
|
|
|
|
# Device model
|
|
if command -v lsblk &> /dev/null; then
|
|
local model
|
|
model=$(lsblk -d -o MODEL "$device" 2>/dev/null | tail -n +2)
|
|
if [[ -n "$model" ]]; then
|
|
echo " Model: $model"
|
|
fi
|
|
fi
|
|
|
|
# Partition information
|
|
if command -v fdisk &> /dev/null; then
|
|
echo " Partitions:"
|
|
fdisk -l "$device" 2>/dev/null | grep -E "^/dev/" || echo " No partitions found"
|
|
fi
|
|
|
|
# Filesystem information
|
|
if command -v blkid &> /dev/null; then
|
|
echo " Filesystems:"
|
|
blkid "$device"* 2>/dev/null || echo " No filesystem information available"
|
|
fi
|
|
|
|
# Mount points
|
|
if command -v findmnt &> /dev/null; then
|
|
echo " Mount points:"
|
|
findmnt "$device"* 2>/dev/null | grep -v "TARGET" || echo " No mount points found"
|
|
fi
|
|
}
|
|
|
|
# Check mount point
|
|
check_mount_point() {
|
|
local mount_point="$1"
|
|
|
|
if [[ -z "$mount_point" ]]; then
|
|
log_error "Mount point is required" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if mount point exists
|
|
if [[ ! -d "$mount_point" ]]; then
|
|
log_error "Mount point directory not found: $mount_point" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if mount point is mounted
|
|
if ! mountpoint -q "$mount_point" 2>/dev/null; then
|
|
log_warning "Mount point not mounted: $mount_point" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check mount point permissions
|
|
if [[ ! -r "$mount_point" ]]; then
|
|
log_error "Mount point not readable: $mount_point" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Mount point check passed: $mount_point" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Calculate disk usage
|
|
calculate_disk_usage() {
|
|
local path="$1"
|
|
|
|
if [[ -z "$path" ]]; then
|
|
path="/"
|
|
fi
|
|
|
|
if [[ ! -d "$path" ]]; then
|
|
log_error "Path not found: $path" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
if command -v df &> /dev/null; then
|
|
log_info "Disk usage for: $path" "bootupd-alternative"
|
|
df -h "$path" 2>/dev/null || log_error "Failed to get disk usage" "bootupd-alternative"
|
|
else
|
|
log_warning "df command not available" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Get available space
|
|
get_available_space() {
|
|
local path="$1"
|
|
|
|
if [[ -z "$path" ]]; then
|
|
path="/"
|
|
fi
|
|
|
|
if [[ ! -d "$path" ]]; then
|
|
log_error "Path not found: $path" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
if command -v df &> /dev/null; then
|
|
local available_space
|
|
available_space=$(df -B1 "$path" 2>/dev/null | awk 'NR==2 {print $4}')
|
|
if [[ -n "$available_space" ]]; then
|
|
echo "$available_space"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
log_error "Failed to get available space" "bootupd-alternative"
|
|
return 1
|
|
}
|
|
|
|
# Check disk space
|
|
check_disk_space() {
|
|
local path="$1"
|
|
local required_space="$2"
|
|
|
|
if [[ -z "$path" ]]; then
|
|
path="/"
|
|
fi
|
|
|
|
if [[ -z "$required_space" ]]; then
|
|
required_space="52428800" # 50MB default for bootloader operations
|
|
fi
|
|
|
|
local available_space
|
|
available_space=$(get_available_space "$path")
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
log_error "Failed to check disk space" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
if [[ $available_space -lt $required_space ]]; then
|
|
log_error "Insufficient disk space. Required: $required_space bytes, Available: $available_space bytes" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Disk space check passed. Available: $available_space bytes" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# List available devices
|
|
list_available_devices() {
|
|
log_info "Available block devices:" "bootupd-alternative"
|
|
|
|
if command -v lsblk &> /dev/null; then
|
|
lsblk -d -o NAME,SIZE,TYPE,MOUNTPOINT 2>/dev/null || log_error "Failed to list devices" "bootupd-alternative"
|
|
elif command -v fdisk &> /dev/null; then
|
|
fdisk -l 2>/dev/null | grep -E "^Disk /" || log_error "Failed to list devices" "bootupd-alternative"
|
|
else
|
|
log_warning "No device listing tools available" "bootupd-alternative"
|
|
fi
|
|
}
|
|
|
|
# Find boot device
|
|
find_boot_device() {
|
|
log_info "Finding boot device..." "bootupd-alternative"
|
|
|
|
# Try to find the device mounted at /boot
|
|
if mountpoint -q /boot 2>/dev/null; then
|
|
local boot_device
|
|
boot_device=$(findmnt -n -o SOURCE /boot 2>/dev/null)
|
|
if [[ -n "$boot_device" ]]; then
|
|
echo "$boot_device"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Try to find the device mounted at /
|
|
local root_device
|
|
root_device=$(findmnt -n -o SOURCE / 2>/dev/null)
|
|
if [[ -n "$root_device" ]]; then
|
|
echo "$root_device"
|
|
return 0
|
|
fi
|
|
|
|
log_error "Could not determine boot device" "bootupd-alternative"
|
|
return 1
|
|
}
|
|
|
|
# Validate device for bootloader installation
|
|
validate_device_for_bootloader() {
|
|
local device="$1"
|
|
local bootloader="$2"
|
|
|
|
if [[ -z "$device" ]]; then
|
|
log_error "Device path is required" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
if [[ -z "$bootloader" ]]; then
|
|
log_error "Bootloader type is required" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Basic device validation
|
|
if ! validate_boot_device "$device"; then
|
|
return 1
|
|
fi
|
|
|
|
# Bootloader-specific validation
|
|
case "$bootloader" in
|
|
"uefi")
|
|
validate_device_for_uefi "$device"
|
|
;;
|
|
"grub")
|
|
validate_device_for_grub "$device"
|
|
;;
|
|
"lilo")
|
|
validate_device_for_lilo "$device"
|
|
;;
|
|
"syslinux")
|
|
validate_device_for_syslinux "$device"
|
|
;;
|
|
*)
|
|
log_error "Unsupported bootloader type: $bootloader" "bootupd-alternative"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Validate device for UEFI
|
|
validate_device_for_uefi() {
|
|
local device="$1"
|
|
|
|
# Check if system supports UEFI
|
|
if [[ ! -d "/sys/firmware/efi" ]]; then
|
|
log_error "System does not support UEFI" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if EFI partition is mounted
|
|
if ! mountpoint -q /boot/efi 2>/dev/null; then
|
|
log_error "EFI partition not mounted at /boot/efi" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Device validation for UEFI passed: $device" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Validate device for GRUB
|
|
validate_device_for_grub() {
|
|
local device="$1"
|
|
|
|
# Check if GRUB tools are available
|
|
if ! command -v grub-install &> /dev/null; then
|
|
log_error "GRUB installation tools not available" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if /boot is accessible
|
|
if [[ ! -d "/boot" ]]; then
|
|
log_error "/boot directory not found" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Device validation for GRUB passed: $device" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Validate device for LILO
|
|
validate_device_for_lilo() {
|
|
local device="$1"
|
|
|
|
# Check if LILO is available
|
|
if ! command -v lilo &> /dev/null; then
|
|
log_error "LILO not available" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if LILO configuration exists
|
|
if [[ ! -f "/etc/lilo.conf" ]]; then
|
|
log_error "LILO configuration not found" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Device validation for LILO passed: $device" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# Validate device for syslinux
|
|
validate_device_for_syslinux() {
|
|
local device="$1"
|
|
|
|
# Check if syslinux is available
|
|
if ! command -v syslinux &> /dev/null; then
|
|
log_error "syslinux not available" "bootupd-alternative"
|
|
return 1
|
|
fi
|
|
|
|
# Check if syslinux configuration exists
|
|
if [[ ! -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
log_warning "syslinux configuration not found, will be created" "bootupd-alternative"
|
|
fi
|
|
|
|
log_debug "Device validation for syslinux passed: $device" "bootupd-alternative"
|
|
return 0
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 05-devices.sh ---
|
|
|
|
# ============================================================================
|
|
# Status Reporting and Monitoring
|
|
# ============================================================================
|
|
# Status and monitoring for Ubuntu uBlue bootupd-alternative Tool
|
|
# Provides system status, monitoring, and information display functions
|
|
|
|
# Show system status
|
|
show_status() {
|
|
log_info "System Status Report" "bootupd-alternative"
|
|
echo "========================================"
|
|
|
|
# System information
|
|
get_system_info
|
|
|
|
# Bootloader information
|
|
get_bootloader_status
|
|
|
|
# Device information
|
|
get_device_status
|
|
|
|
# Backup information
|
|
get_backup_status
|
|
|
|
# Integration status
|
|
get_integration_status
|
|
|
|
echo "========================================"
|
|
log_success "Status report completed" "bootupd-alternative"
|
|
}
|
|
|
|
# Get system information
|
|
get_system_info() {
|
|
log_info "System Information:" "bootupd-alternative"
|
|
|
|
# Operating system
|
|
if [[ -f "/etc/os-release" ]]; then
|
|
local os_name
|
|
os_name=$(grep "^NAME=" /etc/os-release | cut -d'"' -f2)
|
|
echo " OS: $os_name"
|
|
fi
|
|
|
|
# Kernel version
|
|
local kernel_version
|
|
kernel_version=$(uname -r)
|
|
echo " Kernel: $kernel_version"
|
|
|
|
# Architecture
|
|
local architecture
|
|
architecture=$(uname -m)
|
|
echo " Architecture: $architecture"
|
|
|
|
# Hostname
|
|
local hostname
|
|
hostname=$(hostname)
|
|
echo " Hostname: $hostname"
|
|
|
|
# Uptime
|
|
if command -v uptime &> /dev/null; then
|
|
local uptime
|
|
uptime=$(uptime -p 2>/dev/null | sed 's/up //')
|
|
echo " Uptime: $uptime"
|
|
fi
|
|
|
|
# Boot mode
|
|
if [[ -d "/sys/firmware/efi" ]]; then
|
|
echo " Boot Mode: UEFI"
|
|
else
|
|
echo " Boot Mode: Legacy BIOS"
|
|
fi
|
|
}
|
|
|
|
# Get bootloader status
|
|
get_bootloader_status() {
|
|
log_info "Bootloader Status:" "bootupd-alternative"
|
|
|
|
# Detect bootloader type
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
echo " Type: $bootloader"
|
|
|
|
case "$bootloader" in
|
|
"uefi")
|
|
get_uefi_status
|
|
;;
|
|
"grub")
|
|
get_grub_status
|
|
;;
|
|
"lilo")
|
|
get_lilo_status
|
|
;;
|
|
"syslinux")
|
|
get_syslinux_status
|
|
;;
|
|
*)
|
|
echo " Status: Unknown bootloader type"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Get UEFI status
|
|
get_uefi_status() {
|
|
echo " UEFI Status:"
|
|
|
|
# Check EFI partition
|
|
if mountpoint -q /boot/efi 2>/dev/null; then
|
|
echo " EFI Partition: Mounted at /boot/efi"
|
|
else
|
|
echo " EFI Partition: Not mounted"
|
|
fi
|
|
|
|
# Check efibootmgr
|
|
if command -v efibootmgr &> /dev/null; then
|
|
echo " efibootmgr: Available"
|
|
# Get current boot order
|
|
local boot_order
|
|
boot_order=$(efibootmgr 2>/dev/null | grep "BootOrder" | cut -d' ' -f2)
|
|
if [[ -n "$boot_order" ]]; then
|
|
echo " Boot Order: $boot_order"
|
|
fi
|
|
else
|
|
echo " efibootmgr: Not available"
|
|
fi
|
|
}
|
|
|
|
# Get GRUB status
|
|
get_grub_status() {
|
|
echo " GRUB Status:"
|
|
|
|
# Check GRUB configuration
|
|
if [[ -f "/boot/grub/grub.cfg" ]]; then
|
|
echo " Configuration: /boot/grub/grub.cfg exists"
|
|
local config_size
|
|
config_size=$(stat -c %s /boot/grub/grub.cfg 2>/dev/null)
|
|
if [[ -n "$config_size" ]]; then
|
|
echo " Config Size: ${config_size} bytes"
|
|
fi
|
|
else
|
|
echo " Configuration: /boot/grub/grub.cfg not found"
|
|
fi
|
|
|
|
# Check GRUB tools
|
|
if command -v grub-install &> /dev/null; then
|
|
echo " grub-install: Available"
|
|
else
|
|
echo " grub-install: Not available"
|
|
fi
|
|
|
|
if command -v grub-mkconfig &> /dev/null; then
|
|
echo " grub-mkconfig: Available"
|
|
else
|
|
echo " grub-mkconfig: Not available"
|
|
fi
|
|
|
|
# Check GRUB modules
|
|
if [[ -d "/boot/grub/x86_64-efi" ]]; then
|
|
echo " Modules: EFI modules available"
|
|
elif [[ -d "/boot/grub/i386-pc" ]]; then
|
|
echo " Modules: Legacy modules available"
|
|
else
|
|
echo " Modules: No modules found"
|
|
fi
|
|
}
|
|
|
|
# Get LILO status
|
|
get_lilo_status() {
|
|
echo " LILO Status:"
|
|
|
|
# Check LILO configuration
|
|
if [[ -f "/etc/lilo.conf" ]]; then
|
|
echo " Configuration: /etc/lilo.conf exists"
|
|
local config_size
|
|
config_size=$(stat -c %s /etc/lilo.conf 2>/dev/null)
|
|
if [[ -n "$config_size" ]]; then
|
|
echo " Config Size: ${config_size} bytes"
|
|
fi
|
|
else
|
|
echo " Configuration: /etc/lilo.conf not found"
|
|
fi
|
|
|
|
# Check LILO tool
|
|
if command -v lilo &> /dev/null; then
|
|
echo " lilo: Available"
|
|
else
|
|
echo " lilo: Not available"
|
|
fi
|
|
}
|
|
|
|
# Get syslinux status
|
|
get_syslinux_status() {
|
|
echo " syslinux Status:"
|
|
|
|
# Check syslinux configuration
|
|
if [[ -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
echo " Configuration: /boot/syslinux/syslinux.cfg exists"
|
|
local config_size
|
|
config_size=$(stat -c %s /boot/syslinux/syslinux.cfg 2>/dev/null)
|
|
if [[ -n "$config_size" ]]; then
|
|
echo " Config Size: ${config_size} bytes"
|
|
fi
|
|
else
|
|
echo " Configuration: /boot/syslinux/syslinux.cfg not found"
|
|
fi
|
|
|
|
# Check syslinux tool
|
|
if command -v syslinux &> /dev/null; then
|
|
echo " syslinux: Available"
|
|
else
|
|
echo " syslinux: Not available"
|
|
fi
|
|
}
|
|
|
|
# Get device status
|
|
get_device_status() {
|
|
log_info "Device Status:" "bootupd-alternative"
|
|
|
|
# Find boot device
|
|
local boot_device
|
|
boot_device=$(find_boot_device)
|
|
if [[ -n "$boot_device" ]]; then
|
|
echo " Boot Device: $boot_device"
|
|
|
|
# Get device information
|
|
get_device_info "$boot_device"
|
|
else
|
|
echo " Boot Device: Could not determine"
|
|
fi
|
|
|
|
# Check mount points
|
|
echo " Mount Points:"
|
|
if mountpoint -q /boot 2>/dev/null; then
|
|
local boot_mount
|
|
boot_mount=$(findmnt -n -o SOURCE,TARGET,FSTYPE /boot 2>/dev/null)
|
|
echo " /boot: $boot_mount"
|
|
else
|
|
echo " /boot: Not mounted"
|
|
fi
|
|
|
|
if mountpoint -q /boot/efi 2>/dev/null; then
|
|
local efi_mount
|
|
efi_mount=$(findmnt -n -o SOURCE,TARGET,FSTYPE /boot/efi 2>/dev/null)
|
|
echo " /boot/efi: $efi_mount"
|
|
else
|
|
echo " /boot/efi: Not mounted"
|
|
fi
|
|
|
|
# Disk usage
|
|
calculate_disk_usage "/"
|
|
}
|
|
|
|
# Get backup status
|
|
get_backup_status() {
|
|
log_info "Backup Status:" "bootupd-alternative"
|
|
|
|
if [[ ! -d "$BOOTUPD_DIR/backups" ]]; then
|
|
echo " Backups: No backup directory found"
|
|
return
|
|
fi
|
|
|
|
local backup_count=0
|
|
local total_size=0
|
|
|
|
for backup_dir in "$BOOTUPD_DIR/backups"/*; do
|
|
if [[ -d "$backup_dir" ]]; then
|
|
backup_count=$((backup_count + 1))
|
|
local backup_size
|
|
backup_size=$(du -s "$backup_dir" 2>/dev/null | cut -f1)
|
|
if [[ -n "$backup_size" ]]; then
|
|
total_size=$((total_size + backup_size))
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo " Backup Count: $backup_count"
|
|
echo " Total Size: ${total_size} KB"
|
|
|
|
if [[ $backup_count -gt 0 ]]; then
|
|
echo " Recent Backups:"
|
|
for backup_dir in "$BOOTUPD_DIR/backups"/*; do
|
|
if [[ -d "$backup_dir" ]]; then
|
|
local backup_name
|
|
backup_name=$(basename "$backup_dir")
|
|
local backup_date
|
|
backup_date=$(stat -c %y "$backup_dir" 2>/dev/null | cut -d' ' -f1)
|
|
echo " $backup_name (created: $backup_date)"
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Get integration status
|
|
get_integration_status() {
|
|
log_info "Integration Status:" "bootupd-alternative"
|
|
|
|
# Check Ubuntu uBlue configuration
|
|
if [[ -f "/usr/local/etc/ublue-config.sh" ]]; then
|
|
echo " Ubuntu uBlue Config: Available"
|
|
elif [[ -f "/etc/ublue-config.sh" ]]; then
|
|
echo " Ubuntu uBlue Config: Available (system-wide)"
|
|
else
|
|
echo " Ubuntu uBlue Config: Not found"
|
|
fi
|
|
|
|
# Check ComposeFS integration
|
|
if [[ -f "/usr/local/bin/composefs-alternative.sh" ]]; then
|
|
echo " ComposeFS Integration: Available"
|
|
elif [[ -f "/usr/bin/composefs-alternative.sh" ]]; then
|
|
echo " ComposeFS Integration: Available (system-wide)"
|
|
else
|
|
echo " ComposeFS Integration: Not found"
|
|
fi
|
|
|
|
# Check bootloader integration
|
|
if [[ -f "/usr/local/bin/bootc-alternative.sh" ]]; then
|
|
echo " Bootloader Integration: Available"
|
|
elif [[ -f "/usr/bin/bootc-alternative.sh" ]]; then
|
|
echo " Bootloader Integration: Available (system-wide)"
|
|
else
|
|
echo " Bootloader Integration: Not found"
|
|
fi
|
|
|
|
# Check apt-layer integration
|
|
if [[ -f "/usr/local/bin/apt-layer.sh" ]]; then
|
|
echo " APT Layer Integration: Available"
|
|
elif [[ -f "/usr/bin/apt-layer.sh" ]]; then
|
|
echo " APT Layer Integration: Available (system-wide)"
|
|
else
|
|
echo " APT Layer Integration: Not found"
|
|
fi
|
|
}
|
|
|
|
# Check system health
|
|
check_system_health() {
|
|
log_info "System Health Check:" "bootupd-alternative"
|
|
|
|
local health_score=100
|
|
local issues=()
|
|
|
|
# Check bootloader
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
if [[ "$bootloader" == "unknown" ]]; then
|
|
health_score=$((health_score - 20))
|
|
issues+=("Unknown bootloader type")
|
|
fi
|
|
|
|
# Check EFI partition for UEFI systems
|
|
if [[ "$bootloader" == "uefi" ]]; then
|
|
if ! mountpoint -q /boot/efi 2>/dev/null; then
|
|
health_score=$((health_score - 15))
|
|
issues+=("EFI partition not mounted")
|
|
fi
|
|
fi
|
|
|
|
# Check GRUB configuration for GRUB systems
|
|
if [[ "$bootloader" == "grub" ]]; then
|
|
if [[ ! -f "/boot/grub/grub.cfg" ]]; then
|
|
health_score=$((health_score - 15))
|
|
issues+=("GRUB configuration missing")
|
|
fi
|
|
fi
|
|
|
|
# Check disk space
|
|
local available_space
|
|
available_space=$(get_available_space "/")
|
|
if [[ $? -eq 0 ]]; then
|
|
local min_space=104857600 # 100MB
|
|
if [[ $available_space -lt $min_space ]]; then
|
|
health_score=$((health_score - 10))
|
|
issues+=("Low disk space")
|
|
fi
|
|
else
|
|
health_score=$((health_score - 5))
|
|
issues+=("Cannot check disk space")
|
|
fi
|
|
|
|
# Check backup directory
|
|
if [[ ! -d "$BOOTUPD_DIR/backups" ]]; then
|
|
health_score=$((health_score - 5))
|
|
issues+=("No backup directory")
|
|
fi
|
|
|
|
# Report health status
|
|
if [[ $health_score -ge 90 ]]; then
|
|
echo " Health Status: Excellent ($health_score/100)"
|
|
elif [[ $health_score -ge 75 ]]; then
|
|
echo " Health Status: Good ($health_score/100)"
|
|
elif [[ $health_score -ge 60 ]]; then
|
|
echo " Health Status: Fair ($health_score/100)"
|
|
else
|
|
echo " Health Status: Poor ($health_score/100)"
|
|
fi
|
|
|
|
if [[ ${#issues[@]} -gt 0 ]]; then
|
|
echo " Issues Found:"
|
|
for issue in "${issues[@]}"; do
|
|
echo " - $issue"
|
|
done
|
|
else
|
|
echo " Issues Found: None"
|
|
fi
|
|
}
|
|
|
|
# Monitor bootloader changes
|
|
monitor_bootloader_changes() {
|
|
local watch_interval="${1:-60}" # Default 60 seconds
|
|
|
|
log_info "Starting bootloader change monitoring (interval: ${watch_interval}s)" "bootupd-alternative"
|
|
|
|
# Create temporary file for tracking changes
|
|
local temp_file
|
|
temp_file=$(mktemp)
|
|
|
|
# Initial state
|
|
get_bootloader_state > "$temp_file"
|
|
|
|
while true; do
|
|
sleep "$watch_interval"
|
|
|
|
# Get current state
|
|
local current_state
|
|
current_state=$(get_bootloader_state)
|
|
|
|
# Compare with previous state
|
|
if ! diff "$temp_file" <(echo "$current_state") > /dev/null 2>&1; then
|
|
log_warning "Bootloader configuration changes detected!" "bootupd-alternative"
|
|
echo "Changes:"
|
|
diff "$temp_file" <(echo "$current_state") || true
|
|
|
|
# Update state file
|
|
echo "$current_state" > "$temp_file"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Get bootloader state for monitoring
|
|
get_bootloader_state() {
|
|
local bootloader
|
|
bootloader=$(detect_bootloader)
|
|
|
|
case "$bootloader" in
|
|
"grub")
|
|
if [[ -f "/boot/grub/grub.cfg" ]]; then
|
|
stat -c "%Y %s" /boot/grub/grub.cfg
|
|
fi
|
|
;;
|
|
"lilo")
|
|
if [[ -f "/etc/lilo.conf" ]]; then
|
|
stat -c "%Y %s" /etc/lilo.conf
|
|
fi
|
|
;;
|
|
"syslinux")
|
|
if [[ -f "/boot/syslinux/syslinux.cfg" ]]; then
|
|
stat -c "%Y %s" /boot/syslinux/syslinux.cfg
|
|
fi
|
|
;;
|
|
"uefi")
|
|
if command -v efibootmgr &> /dev/null; then
|
|
efibootmgr 2>/dev/null | grep "BootOrder"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# --- END OF SCRIPTLET: 06-status.sh ---
|
|
|
|
# ============================================================================
|
|
# Main Dispatch and Help
|
|
# ============================================================================
|
|
# Main execution and command dispatch for Ubuntu uBlue bootupd-alternative Tool
|
|
# Show usage information
|
|
show_usage() {
|
|
cat << EOF
|
|
Ubuntu uBlue bootupd-alternative Tool - Enhanced Bootloader Management
|
|
Provides advanced bootloader management for Ubuntu uBlue systems
|
|
|
|
Usage:
|
|
bootupd-alternative install <device>
|
|
# Install bootloader to specified device
|
|
|
|
bootupd-alternative update
|
|
# Update bootloader configuration
|
|
|
|
bootupd-alternative status
|
|
# Show current bootloader status
|
|
|
|
bootupd-alternative backup [name]
|
|
# Create backup of current bootloader configuration
|
|
|
|
bootupd-alternative restore <backup-name>
|
|
# Restore bootloader configuration from backup
|
|
|
|
bootupd-alternative list-backups
|
|
# List available backups
|
|
|
|
bootupd-alternative add-entry <title> <kernel> [options]
|
|
# Add new boot entry
|
|
|
|
bootupd-alternative remove-entry <title>
|
|
# Remove boot entry
|
|
|
|
bootupd-alternative list-entries
|
|
# List current boot entries
|
|
|
|
bootupd-alternative set-default <title>
|
|
# Set default boot entry
|
|
|
|
bootupd-alternative info <device>
|
|
# Show device information
|
|
|
|
bootupd-alternative help
|
|
# Show this help message
|
|
|
|
Examples:
|
|
# Install bootloader to device
|
|
sudo bootupd-alternative install /dev/sda
|
|
|
|
# Update bootloader configuration
|
|
sudo bootupd-alternative update
|
|
|
|
# Create backup
|
|
sudo bootupd-alternative backup before-update
|
|
|
|
# Restore backup
|
|
sudo bootupd-alternative restore before-update
|
|
|
|
# Add custom boot entry
|
|
sudo bootupd-alternative add-entry "Ubuntu Recovery" /boot/vmlinuz-5.15.0-rc1
|
|
|
|
# Set default boot entry
|
|
sudo bootupd-alternative set-default "Ubuntu uBlue"
|
|
|
|
# Show device information
|
|
sudo bootupd-alternative info /dev/sda
|
|
|
|
Description:
|
|
bootupd-alternative provides comprehensive bootloader management for Ubuntu uBlue systems.
|
|
It supports multiple bootloader types (GRUB, UEFI, LILO, syslinux) and provides
|
|
advanced features like backup/restore, custom boot entries, and device management.
|
|
|
|
KEY FEATURES:
|
|
- Multi-bootloader support (GRUB, UEFI, LILO, syslinux)
|
|
- Automatic bootloader detection and configuration
|
|
- Backup and restore functionality
|
|
- Custom boot entry management
|
|
- Device validation and information
|
|
- Integration with Ubuntu uBlue configuration system
|
|
|
|
SECURITY FEATURES:
|
|
- Input validation and sanitization
|
|
- Path traversal protection
|
|
- Privilege escalation prevention
|
|
- Secure temporary file handling
|
|
|
|
INTEGRATION:
|
|
- Ubuntu uBlue configuration system
|
|
- ComposeFS backend support
|
|
- Bootloader integration scripts
|
|
- Unified logging system
|
|
EOF
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
# Initialize directories
|
|
init_directories
|
|
|
|
# Check dependencies
|
|
check_dependencies
|
|
|
|
# Check system bootability
|
|
check_system_bootability
|
|
|
|
# Check filesystems
|
|
check_filesystems
|
|
|
|
# Parse command line arguments
|
|
case "${1:-}" in
|
|
--help|-h)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
install)
|
|
if [ -z "${2:-}" ]; then
|
|
log_error "Device required for install" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
install_bootloader "$2"
|
|
;;
|
|
update)
|
|
update_bootloader
|
|
;;
|
|
status)
|
|
show_status
|
|
;;
|
|
backup)
|
|
local backup_name="${2:-backup-$(date +%Y%m%d-%H%M%S)}"
|
|
create_backup "$backup_name"
|
|
;;
|
|
restore)
|
|
if [ -z "${2:-}" ]; then
|
|
log_error "Backup name required for restore" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
restore_backup "$2"
|
|
;;
|
|
list-backups)
|
|
list_backups
|
|
;;
|
|
add-entry)
|
|
if [ $# -lt 3 ]; then
|
|
log_error "Title and kernel required for add-entry" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
local title="$2"
|
|
local kernel="$3"
|
|
shift 3
|
|
local options=("$@")
|
|
add_boot_entry "$title" "$kernel" "${options[@]}"
|
|
;;
|
|
remove-entry)
|
|
if [ -z "${2:-}" ]; then
|
|
log_error "Title required for remove-entry" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
remove_boot_entry "$2"
|
|
;;
|
|
list-entries)
|
|
list_boot_entries
|
|
;;
|
|
set-default)
|
|
if [ -z "${2:-}" ]; then
|
|
log_error "Title required for set-default" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
set_default_entry "$2"
|
|
;;
|
|
info)
|
|
if [ -z "${2:-}" ]; then
|
|
log_error "Device required for info" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
fi
|
|
get_device_info "$2"
|
|
;;
|
|
"")
|
|
log_error "No arguments provided" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
*)
|
|
log_error "Unknown command: $1" "bootupd-alternative"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run main function
|
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
main "$@"
|
|
fi
|
|
|
|
# --- END OF SCRIPTLET: 99-main.sh ---
|
|
|
|
# ============================================================================
|
|
# Embedded Configuration Files
|
|
# ============================================================================
|
|
|
|
# ============================================================================
|
|
# External Configuration Loading (Future Enhancement)
|
|
# ============================================================================
|
|
|
|
# Function to load configuration from external files
|
|
# Usage: load_config_from_file "config-name"
|
|
load_config_from_file() {
|
|
local config_name="$1"
|
|
local config_file="/etc/bootupd/config/${config_name}.json"
|
|
if [[ -f "$config_file" ]]; then
|
|
jq -r '.' "$config_file"
|
|
else
|
|
log_error "Configuration file not found: $config_file" "bootupd-alternative"
|
|
exit 1
|
|
fi
|
|
}
|
|
|