#!/bin/bash # CMtec Update System - Role Management Library # Handles role-based installation system # Load roles from configuration load_roles() { local hostname="${SYSTEM_INFO[HOSTNAME]}" local distro="${SYSTEM_INFO[DISTRO]}" log INFO "Loading role configuration for $hostname ($distro)..." # Initialize all roles to "no" declare -gA ROLES local all_roles=( "DESKTOP_BASE" "DESKTOP_WORK" "CODE" "TERMINAL" "HYPERLAND" "MUSIC" "GAME" "VR" "LAB" "BT" "NVIDIA_GPU" "NVIDIA_1080_GPU" "WSL" "DEVELOPMENT" "AUDIO_PRODUCTION" ) for role in "${all_roles[@]}"; do ROLES["$role"]="no" done # Load distro-specific role configuration local role_config_file="$SCRIPT_DIR/config/${distro}-roles.conf" if [ -f "$role_config_file" ]; then source "$role_config_file" log SUCCESS "Loaded role configuration from $role_config_file" else log WARNING "Role configuration file not found: $role_config_file" # Fall back to hardcoded assignments assign_default_roles fi # Apply hostname-specific role assignments assign_hostname_roles "$hostname" # Apply auto-detected roles based on system capabilities assign_auto_detected_roles # Validate role dependencies validate_role_dependencies log SUCCESS "Role configuration completed" } # Assign default roles based on system capabilities assign_default_roles() { log INFO "Assigning default roles based on system detection..." # Basic roles based on system type case "${SYSTEM_INFO[DISTRO]}" in "arch") ROLES["TERMINAL"]="yes" if supports_feature "desktop"; then ROLES["DESKTOP_BASE"]="yes" ROLES["HYPERLAND"]="yes" fi ;; "ubuntu") ROLES["TERMINAL"]="yes" if supports_feature "desktop"; then ROLES["DESKTOP_BASE"]="yes" fi ;; esac # WSL-specific roles if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then ROLES["WSL"]="yes" ROLES["DEVELOPMENT"]="yes" # Disable desktop-specific roles in WSL ROLES["DESKTOP_BASE"]="no" ROLES["HYPERLAND"]="no" ROLES["GAME"]="no" ROLES["VR"]="no" fi # GPU-based roles if [ "${SYSTEM_INFO[NVIDIA_GPU]}" == "yes" ]; then ROLES["NVIDIA_GPU"]="yes" if echo "${SYSTEM_INFO[GPU_INFO]:-}" | grep -qi "GTX 1080"; then ROLES["NVIDIA_1080_GPU"]="yes" fi fi # Bluetooth support if [ "${SYSTEM_INFO[BLUETOOTH]}" == "yes" ]; then ROLES["BT"]="yes" fi } # Assign hostname-specific roles assign_hostname_roles() { local hostname="$1" case "$hostname" in "CMBOX") ROLES["DESKTOP_BASE"]="yes" ROLES["DESKTOP_WORK"]="yes" ROLES["CODE"]="yes" ROLES["TERMINAL"]="yes" ROLES["HYPERLAND"]="yes" ROLES["MUSIC"]="yes" ;; "STEAMBOX") ROLES["GAME"]="yes" ROLES["VR"]="yes" ROLES["DESKTOP_BASE"]="yes" ROLES["NVIDIA_GPU"]="yes" ROLES["TERMINAL"]="yes" ROLES["HYPERLAND"]="yes" ;; "LABBOX") ROLES["DESKTOP_BASE"]="yes" ROLES["CODE"]="yes" ROLES["TERMINAL"]="yes" ROLES["HYPERLAND"]="yes" ROLES["LAB"]="yes" ROLES["BT"]="yes" ;; "SIMONBOX") ROLES["GAME"]="yes" ROLES["VR"]="yes" ROLES["DESKTOP_BASE"]="yes" ROLES["NVIDIA_1080_GPU"]="yes" ROLES["TERMINAL"]="yes" ROLES["HYPERLAND"]="yes" ROLES["BT"]="yes" ;; *) log INFO "No specific role configuration for hostname: $hostname" ;; esac } # Assign roles based on auto-detected system capabilities assign_auto_detected_roles() { log INFO "Auto-detecting additional roles based on system capabilities..." # Development environment detection if command_exists git && (command_exists nvim || command_exists vim); then ROLES["DEVELOPMENT"]="yes" fi # Audio production detection if [ "${SYSTEM_INFO[AUDIO_SYSTEM]}" == "pipewire" ] && supports_feature "desktop"; then # Only enable if desktop is available and pipewire is present if [ "${ROLES[DESKTOP_BASE]}" == "yes" ]; then # Don't auto-enable audio production, leave it to specific hostname configs log INFO "Pipewire detected - audio production capabilities available" fi fi # Gaming detection based on GPU if [ "${SYSTEM_INFO[NVIDIA_GPU]}" == "yes" ] && supports_feature "desktop"; then if [ "${ROLES[GAME]}" == "no" ]; then log INFO "Gaming-capable GPU detected but gaming role not enabled" fi fi } # Validate role dependencies and conflicts validate_role_dependencies() { log INFO "Validating role dependencies..." # Desktop dependencies local desktop_roles=("DESKTOP_WORK" "GAME" "VR" "MUSIC" "HYPERLAND") for role in "${desktop_roles[@]}"; do if [ "${ROLES[$role]}" == "yes" ] && [ "${ROLES[DESKTOP_BASE]}" == "no" ]; then log WARNING "$role requires DESKTOP_BASE - enabling it" ROLES["DESKTOP_BASE"]="yes" fi done # VR requires Gaming if [ "${ROLES[VR]}" == "yes" ] && [ "${ROLES[GAME]}" == "no" ]; then log WARNING "VR role requires GAME role - enabling it" ROLES["GAME"]="yes" fi # NVIDIA GPU roles if [ "${ROLES[NVIDIA_1080_GPU]}" == "yes" ] && [ "${ROLES[NVIDIA_GPU]}" == "no" ]; then log WARNING "NVIDIA_1080_GPU requires NVIDIA_GPU - enabling it" ROLES["NVIDIA_GPU"]="yes" fi # WSL conflicts if [ "${ROLES[WSL]}" == "yes" ]; then local wsl_conflicts=("HYPERLAND" "VR") for role in "${wsl_conflicts[@]}"; do if [ "${ROLES[$role]}" == "yes" ]; then log WARNING "$role is not compatible with WSL - disabling it" ROLES["$role"]="no" fi done fi # Container conflicts if [ "${SYSTEM_INFO[CONTAINER]}" == "yes" ]; then local container_conflicts=("HYPERLAND" "VR" "GAME" "NVIDIA_GPU") for role in "${container_conflicts[@]}"; do if [ "${ROLES[$role]}" == "yes" ]; then log WARNING "$role is not compatible with containers - disabling it" ROLES["$role"]="no" fi done fi } # Get enabled roles get_enabled_roles() { local enabled_roles=() for role in "${!ROLES[@]}"; do if [ "${ROLES[$role]}" == "yes" ]; then enabled_roles+=("$role") fi done echo "${enabled_roles[@]}" } # Check if a specific role is enabled role_enabled() { local role="$1" [ "${ROLES[$role]}" == "yes" ] } # Get role count get_role_count() { local count=0 for role in "${!ROLES[@]}"; do if [ "${ROLES[$role]}" == "yes" ]; then ((count++)) fi done echo $count } # Interactive role selection (if interactive mode is enabled) interactive_role_selection() { if [ "$INTERACTIVE" != "true" ]; then return fi log SECTION "Interactive Role Selection" echo -e "${YELLOW}Current role configuration:${RESET}" local all_roles=($(printf '%s\n' "${!ROLES[@]}" | sort)) for role in "${all_roles[@]}"; do local status="${ROLES[$role]}" local status_icon="${GREEN}${CHECK}${RESET}" [ "$status" == "no" ] && status_icon="${RED}${CROSS}${RESET}" echo -e " $status_icon $role" done echo if confirm "Modify role configuration?"; then modify_roles_interactively fi } # Interactive role modification modify_roles_interactively() { local all_roles=($(printf '%s\n' "${!ROLES[@]}" | sort)) for role in "${all_roles[@]}"; do local current_status="${ROLES[$role]}" local opposite_status="yes" [ "$current_status" == "yes" ] && opposite_status="no" if confirm "Toggle $role (currently: $current_status) to $opposite_status?"; then ROLES["$role"]="$opposite_status" log INFO "$role toggled to $opposite_status" fi done # Re-validate after interactive changes validate_role_dependencies } # Export roles for use in other scripts export_roles() { for role in "${!ROLES[@]}"; do export "ROLE_${role}=${ROLES[$role]}" done } # Get roles that should be installed by category get_roles_by_category() { local category="$1" local matching_roles=() case "$category" in "desktop") for role in DESKTOP_BASE DESKTOP_WORK HYPERLAND; do [ "${ROLES[$role]}" == "yes" ] && matching_roles+=("$role") done ;; "development") for role in CODE DEVELOPMENT TERMINAL; do [ "${ROLES[$role]}" == "yes" ] && matching_roles+=("$role") done ;; "gaming") for role in GAME VR NVIDIA_GPU NVIDIA_1080_GPU; do [ "${ROLES[$role]}" == "yes" ] && matching_roles+=("$role") done ;; "media") for role in MUSIC; do [ "${ROLES[$role]}" == "yes" ] && matching_roles+=("$role") done ;; "hardware") for role in BT LAB; do [ "${ROLES[$role]}" == "yes" ] && matching_roles+=("$role") done ;; *) log WARNING "Unknown role category: $category" return 1 ;; esac echo "${matching_roles[@]}" } # Source guard to prevent double-sourcing if [ -z "$ROLES_LIB_LOADED" ]; then ROLES_LIB_LOADED=true fi