linuxbox/update/lib/detect.sh

266 lines
7.7 KiB
Bash

#!/bin/bash
# CMtec Update System - OS Detection Library
# Detects operating system, distribution, version, and environment
# Initialize system info array
declare -A SYSTEM_INFO
# Detect operating system and distribution
detect_system() {
log INFO "Detecting system information..."
# Basic OS detection
SYSTEM_INFO[OS]=$(uname -s)
SYSTEM_INFO[ARCH]=$(uname -m)
SYSTEM_INFO[HOSTNAME]=$(hostname | tr '[:lower:]' '[:upper:]')
SYSTEM_INFO[KERNEL]=$(uname -r)
# Detect distribution
if [ -f /etc/os-release ]; then
source /etc/os-release
SYSTEM_INFO[DISTRO]=$(echo "$ID" | tr '[:upper:]' '[:lower:]')
SYSTEM_INFO[VERSION]="$VERSION_ID"
SYSTEM_INFO[PRETTY_NAME]="$PRETTY_NAME"
elif [ -f /etc/arch-release ]; then
SYSTEM_INFO[DISTRO]="arch"
SYSTEM_INFO[VERSION]="rolling"
SYSTEM_INFO[PRETTY_NAME]="Arch Linux"
elif [ -f /etc/debian_version ]; then
SYSTEM_INFO[DISTRO]="debian"
SYSTEM_INFO[VERSION]=$(cat /etc/debian_version)
SYSTEM_INFO[PRETTY_NAME]="Debian GNU/Linux"
else
log ERROR "Unable to detect Linux distribution"
return 1
fi
# Detect environment specifics
detect_environment
# Log system information
log SUCCESS "System detected: ${SYSTEM_INFO[PRETTY_NAME]} (${SYSTEM_INFO[DISTRO]})"
log INFO "Hostname: ${SYSTEM_INFO[HOSTNAME]}"
log INFO "Architecture: ${SYSTEM_INFO[ARCH]}"
log INFO "Environment: ${SYSTEM_INFO[ENVIRONMENT]}"
return 0
}
# Detect specific environment (WSL, Desktop, Container, etc.)
detect_environment() {
local env_flags=()
# Check for WSL
if [[ "$(systemd-detect-virt 2>/dev/null)" == *"wsl"* ]] || \
[ -f /proc/sys/fs/binfmt_misc/WSLInterop ] || \
grep -qi "microsoft" /proc/version 2>/dev/null; then
env_flags+=("wsl")
SYSTEM_INFO[WSL]="yes"
else
SYSTEM_INFO[WSL]="no"
fi
# Check for container environment
if [ -f /.dockerenv ] || \
[[ "$(systemd-detect-virt 2>/dev/null)" == "docker" ]] || \
[[ "$(systemd-detect-virt 2>/dev/null)" == "podman" ]]; then
env_flags+=("container")
SYSTEM_INFO[CONTAINER]="yes"
else
SYSTEM_INFO[CONTAINER]="no"
fi
# Check for desktop environment
detect_desktop_environment
# Check for virtualization
local virt=$(systemd-detect-virt 2>/dev/null)
if [ "$virt" != "none" ] && [ -n "$virt" ]; then
env_flags+=("vm")
SYSTEM_INFO[VIRTUALIZATION]="$virt"
else
SYSTEM_INFO[VIRTUALIZATION]="none"
fi
# Set environment string
if [ ${#env_flags[@]} -gt 0 ]; then
SYSTEM_INFO[ENVIRONMENT]=$(IFS=,; echo "${env_flags[*]}")
else
SYSTEM_INFO[ENVIRONMENT]="native"
fi
}
# Detect desktop environment
detect_desktop_environment() {
local desktop_env=""
# Check for various desktop environments
if [ -n "$XDG_CURRENT_DESKTOP" ]; then
desktop_env="$XDG_CURRENT_DESKTOP"
elif [ -n "$DESKTOP_SESSION" ]; then
desktop_env="$DESKTOP_SESSION"
elif [ -n "$GDMSESSION" ]; then
desktop_env="$GDMSESSION"
elif pgrep -x "gnome-session" >/dev/null; then
desktop_env="GNOME"
elif pgrep -x "kded5" >/dev/null || pgrep -x "kded6" >/dev/null; then
desktop_env="KDE"
elif pgrep -x "xfce4-session" >/dev/null; then
desktop_env="XFCE"
elif pgrep -x "hyprland" >/dev/null; then
desktop_env="Hyprland"
fi
# Special checks for distribution-specific detection
case "${SYSTEM_INFO[DISTRO]}" in
"ubuntu")
if dpkg -l | grep -q "ubuntu-desktop"; then
SYSTEM_INFO[DESKTOP]="yes"
SYSTEM_INFO[DESKTOP_ENV]="${desktop_env:-GNOME}"
else
SYSTEM_INFO[DESKTOP]="no"
fi
;;
"arch")
if pacman -Qs | grep -E "(gnome|kde|xfce|hyprland)" >/dev/null; then
SYSTEM_INFO[DESKTOP]="yes"
SYSTEM_INFO[DESKTOP_ENV]="$desktop_env"
else
SYSTEM_INFO[DESKTOP]="no"
fi
;;
*)
if [ -n "$desktop_env" ]; then
SYSTEM_INFO[DESKTOP]="yes"
SYSTEM_INFO[DESKTOP_ENV]="$desktop_env"
else
SYSTEM_INFO[DESKTOP]="no"
fi
;;
esac
}
# Detect hardware capabilities
detect_hardware() {
log INFO "Detecting hardware capabilities..."
# GPU Detection
detect_gpu
# Audio system detection
detect_audio_system
# Network capabilities
detect_network_capabilities
log SUCCESS "Hardware detection completed"
}
# Detect GPU type and capabilities
detect_gpu() {
local gpu_info=$(lspci | grep -i vga 2>/dev/null)
SYSTEM_INFO[NVIDIA_GPU]="no"
SYSTEM_INFO[NVIDIA_1080_GPU]="no"
SYSTEM_INFO[AMD_GPU]="no"
SYSTEM_INFO[INTEL_GPU]="no"
if echo "$gpu_info" | grep -qi nvidia; then
SYSTEM_INFO[NVIDIA_GPU]="yes"
if echo "$gpu_info" | grep -qi "GTX 1080\\|RTX"; then
SYSTEM_INFO[NVIDIA_1080_GPU]="yes"
fi
log INFO "NVIDIA GPU detected"
fi
if echo "$gpu_info" | grep -qi "amd\\|radeon"; then
SYSTEM_INFO[AMD_GPU]="yes"
log INFO "AMD GPU detected"
fi
if echo "$gpu_info" | grep -qi intel; then
SYSTEM_INFO[INTEL_GPU]="yes"
log INFO "Intel GPU detected"
fi
}
# Detect audio system
detect_audio_system() {
if command_exists pulseaudio; then
SYSTEM_INFO[AUDIO_SYSTEM]="pulseaudio"
elif command_exists pipewire; then
SYSTEM_INFO[AUDIO_SYSTEM]="pipewire"
elif command_exists alsa; then
SYSTEM_INFO[AUDIO_SYSTEM]="alsa"
else
SYSTEM_INFO[AUDIO_SYSTEM]="unknown"
fi
log INFO "Audio system: ${SYSTEM_INFO[AUDIO_SYSTEM]}"
}
# Detect network capabilities
detect_network_capabilities() {
SYSTEM_INFO[BLUETOOTH]="no"
SYSTEM_INFO[WIFI]="no"
if command_exists bluetoothctl || [ -d /sys/class/bluetooth ]; then
SYSTEM_INFO[BLUETOOTH]="yes"
fi
if ip link show | grep -q "wlan\\|wifi\\|wireless" || \
nmcli dev status 2>/dev/null | grep -q wifi; then
SYSTEM_INFO[WIFI]="yes"
fi
}
# Get system capabilities summary
get_capabilities() {
local capabilities=()
[ "${SYSTEM_INFO[DESKTOP]}" == "yes" ] && capabilities+=("desktop")
[ "${SYSTEM_INFO[NVIDIA_GPU]}" == "yes" ] && capabilities+=("nvidia")
[ "${SYSTEM_INFO[AMD_GPU]}" == "yes" ] && capabilities+=("amd")
[ "${SYSTEM_INFO[BLUETOOTH]}" == "yes" ] && capabilities+=("bluetooth")
[ "${SYSTEM_INFO[WIFI]}" == "yes" ] && capabilities+=("wifi")
[ "${SYSTEM_INFO[WSL]}" == "yes" ] && capabilities+=("wsl")
[ "${SYSTEM_INFO[CONTAINER]}" == "yes" ] && capabilities+=("container")
echo "${capabilities[@]}"
}
# Check if current system supports a specific feature
supports_feature() {
local feature="$1"
case "$feature" in
"desktop")
[ "${SYSTEM_INFO[DESKTOP]}" == "yes" ]
;;
"gpu")
[ "${SYSTEM_INFO[NVIDIA_GPU]}" == "yes" ] || \
[ "${SYSTEM_INFO[AMD_GPU]}" == "yes" ]
;;
"nvidia")
[ "${SYSTEM_INFO[NVIDIA_GPU]}" == "yes" ]
;;
"bluetooth")
[ "${SYSTEM_INFO[BLUETOOTH]}" == "yes" ]
;;
"wsl")
[ "${SYSTEM_INFO[WSL]}" == "yes" ]
;;
"container")
[ "${SYSTEM_INFO[CONTAINER]}" == "yes" ]
;;
*)
return 1
;;
esac
}
# Source guard to prevent double-sourcing
if [ -z "$DETECT_LIB_LOADED" ]; then
DETECT_LIB_LOADED=true
fi