New update script

This commit is contained in:
Christoffer Martinsson 2025-09-11 11:16:27 +02:00
parent 9fa71efe70
commit d6e16d1155
20 changed files with 3347 additions and 7 deletions

View File

@ -6,14 +6,18 @@ esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
HISTCONTROL=ignoreboth:erasedups
# append to the history file, don't overwrite it
shopt -s histappend
# Save multi-line commands as single entry
shopt -s cmdhist
# Save history immediately after each command
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
HISTSIZE=10000
HISTFILESIZE=20000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.

View File

@ -135,10 +135,6 @@ cursor {
hide_on_key_press = true
}
gestures {
workspace_swipe = false
}
device {
name = elecom-trackball-mouse-deft-pro-trackball-1
sensitivity = 0.7

46
update/arch/arch.sh Normal file
View File

@ -0,0 +1,46 @@
#!/bin/bash
# Arch Linux Master Module
# Loads all Arch-specific modules and orchestrates installation
# Source all Arch modules
source "$SCRIPT_DIR/arch/system.sh"
source "$SCRIPT_DIR/arch/development.sh"
source "$SCRIPT_DIR/arch/terminal.sh"
source "$SCRIPT_DIR/arch/desktop.sh"
source "$SCRIPT_DIR/arch/gaming.sh"
source "$SCRIPT_DIR/arch/music.sh"
source "$SCRIPT_DIR/arch/lab.sh"
# Main Arch installation function
arch_install_all() {
log SECTION "Starting Arch Linux installation"
# System setup (drivers, core system, Hyprland)
arch_setup_system
# Terminal environment (CLI tools, modern replacements)
arch_setup_terminal
# Development environment (languages, LSPs, tools)
arch_setup_development
# Desktop applications (GUI apps, work tools)
arch_setup_desktop
# Gaming setup (Steam, Wine, VR)
arch_setup_gaming
# Music production
arch_setup_music_production
# Lab equipment
arch_setup_lab
log SUCCESS "Arch Linux installation completed"
}
# Source guard
if [ -z "$ARCH_MASTER_LOADED" ]; then
ARCH_MASTER_LOADED=true
fi

287
update/arch/desktop.sh Normal file
View File

@ -0,0 +1,287 @@
#!/bin/bash
# Arch Linux Desktop Applications Module
# Handles desktop applications, fonts, and user applications
arch_install_desktop_base() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing desktop base applications"
local section_start=$(date +%s)
if confirm "Install base desktop applications?"; then
local desktop_packages=(
cameractrls feh
)
install_packages "${desktop_packages[@]}"
# Essential Flatpak applications
local flatpak_apps=(
"com.discordapp.Discord"
"com.behringer.XAirEdit"
"com.github.vikdevelop.timer"
"io.github.efogdev.mpris-timer"
"org.remmina.Remmina"
)
for app in "${flatpak_apps[@]}"; do
install_flatpak_apps "$app"
done
# Brave browser from AUR
install_aur_packages brave-bin
log SUCCESS "Desktop base applications installed $(show_timer $section_start)"
fi
}
arch_install_fonts() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing fonts"
local section_start=$(date +%s)
if confirm "Install additional fonts?"; then
local font_packages=(
noto-fonts poppler-data adobe-source-code-pro-fonts
ttf-liberation ttf-dejavu
)
install_packages "${font_packages[@]}"
log SUCCESS "Fonts installed $(show_timer $section_start)"
fi
}
arch_install_desktop_work() {
if ! role_enabled "DESKTOP_WORK"; then
return 0
fi
log SECTION "Installing desktop work applications"
local section_start=$(date +%s)
if confirm "Install work applications (KiCad, FreeCad, etc.)?"; then
# Applications from official repos
local work_packages=(
kicad freecad
)
install_packages "${work_packages[@]}"
# Work applications from Flatpak
local work_flatpaks=(
"org.kde.krita"
"com.prusa3d.PrusaSlicer"
"com.jgraph.drawio.desktop"
"org.gimp.GIMP"
)
for app in "${work_flatpaks[@]}"; do
install_flatpak_apps "$app"
done
log SUCCESS "Desktop work applications installed $(show_timer $section_start)"
fi
}
arch_install_media_apps() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing media applications"
local section_start=$(date +%s)
if confirm "Install media applications (video, image viewers, etc.)?"; then
local media_packages=(
mpv vlc imv imagemagick
)
install_packages "${media_packages[@]}"
# Media Flatpak applications
local media_flatpaks=(
"org.videolan.VLC"
"org.kde.kdenlive"
)
for app in "${media_flatpaks[@]}"; do
if confirm "Install $(basename $app)?"; then
install_flatpak_apps "$app"
fi
done
log SUCCESS "Media applications installed $(show_timer $section_start)"
fi
}
arch_install_office_apps() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing office applications"
local section_start=$(date +%s)
if confirm "Install office applications?"; then
local office_flatpaks=(
"org.libreoffice.LibreOffice"
"com.github.jeromerobert.pdfarranger"
)
for app in "${office_flatpaks[@]}"; do
if confirm "Install $(basename $app)?"; then
install_flatpak_apps "$app"
fi
done
log SUCCESS "Office applications installed $(show_timer $section_start)"
fi
}
arch_install_system_utilities() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing system utilities"
local section_start=$(date +%s)
if confirm "Install system utilities (file managers, etc.)?"; then
local utility_packages=(
thunar thunar-archive-plugin thunar-media-tags-plugin
file-roller gparted
)
install_packages "${utility_packages[@]}"
log SUCCESS "System utilities installed $(show_timer $section_start)"
fi
}
arch_install_communication() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing communication applications"
local section_start=$(date +%s)
if confirm "Install communication apps (beyond Discord)?"; then
local comm_flatpaks=(
"com.slack.Slack"
"org.signal.Signal"
"us.zoom.Zoom"
)
for app in "${comm_flatpaks[@]}"; do
if confirm "Install $(basename $app)?"; then
install_flatpak_apps "$app"
fi
done
log SUCCESS "Communication applications installed $(show_timer $section_start)"
fi
}
arch_install_development_gui() {
if ! role_enabled "DESKTOP_BASE" || (! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"); then
return 0
fi
log SECTION "Installing GUI development tools"
local section_start=$(date +%s)
if confirm "Install GUI development tools?"; then
local dev_gui_flatpaks=(
"com.visualstudio.code"
"com.jetbrains.IntelliJ-IDEA-Community"
)
for app in "${dev_gui_flatpaks[@]}"; do
if confirm "Install $(basename $app)?"; then
install_flatpak_apps "$app"
fi
done
log SUCCESS "GUI development tools installed $(show_timer $section_start)"
fi
}
arch_setup_desktop_environment() {
if ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Setting up desktop environment"
local section_start=$(date +%s)
# Setup XDG directories
mkdir -p ~/Desktop ~/Documents ~/Downloads ~/Music ~/Pictures ~/Videos
# Set up mime types and default applications
if command_exists xdg-settings; then
# Set default browser if Brave is installed
if command_exists brave; then
xdg-settings set default-web-browser brave-browser.desktop
fi
fi
log SUCCESS "Desktop environment configured $(show_timer $section_start)"
}
# Special applications for specific hostnames
arch_install_hostname_specific() {
local hostname="${SYSTEM_INFO[HOSTNAME]}"
case "$hostname" in
"CMBOX")
log SECTION "Installing CMBOX-specific applications"
if confirm "Install CMBOX-specific apps?"; then
# CMBOX might need specific tools for work
local cmbox_flatpaks=("com.obsproject.Studio")
for app in "${cmbox_flatpaks[@]}"; do
install_flatpak_apps "$app"
done
fi
;;
"LABBOX")
log SECTION "Installing LABBOX-specific applications"
if confirm "Install LABBOX-specific apps?"; then
# Lab-specific GUI tools
local lab_packages=("wireshark-qt")
install_packages "${lab_packages[@]}"
fi
;;
esac
}
# Main function to run all desktop setup
arch_setup_desktop() {
if ! role_enabled "DESKTOP_BASE"; then
log INFO "Desktop roles not enabled - skipping desktop setup"
return 0
fi
arch_install_desktop_base
arch_install_fonts
arch_install_desktop_work
arch_install_media_apps
arch_install_office_apps
arch_install_system_utilities
arch_install_communication
arch_install_development_gui
arch_setup_desktop_environment
arch_install_hostname_specific
}
# Source guard
if [ -z "$ARCH_DESKTOP_LOADED" ]; then
ARCH_DESKTOP_LOADED=true
fi

283
update/arch/development.sh Normal file
View File

@ -0,0 +1,283 @@
#!/bin/bash
# Arch Linux Development Environment Module
# Handles programming languages, tools, and development setup
arch_install_development_languages() {
log SECTION "Installing development languages and runtimes"
local section_start=$(date +%s)
if confirm "Install development languages (Node.js, Go, PHP, Ruby, Julia, Java)?"; then
local dev_packages=(
nodejs npm go php luarocks composer jdk-openjdk julia ruby
)
install_packages "${dev_packages[@]}"
# Configure npm prefix
npm config set prefix "${HOME}/.npm"
log SUCCESS "Development languages installed $(show_timer $section_start)"
fi
}
arch_install_neovim() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT" && ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing Neovim"
local section_start=$(date +%s)
if confirm "Install Neovim (git version)?"; then
# Install git version of neovim from AUR
install_aur_packages neovim-git-bin
# Install Node.js integration
if command_exists npm; then
sudo npm install -g neovim
fi
# Setup Neovim configuration
mkdir -p ~/.config/nvim
ln -sf ~/linuxbox/config/nvim/init.lua ~/.config/nvim/init.lua
# Sync plugins if lazy directory exists
if [ -d ~/.local/share/nvim/lazy ]; then
nvim --headless "+Lazy! sync" +qa || true
fi
log SUCCESS "Neovim installed $(show_timer $section_start)"
fi
}
arch_install_rust_tools() {
log SECTION "Installing Rust development tools"
local section_start=$(date +%s)
if confirm "Install Rust tools (cargo packages)?"; then
# Essential Rust tools
local rust_tools=(
"tree-sitter-cli"
"ripgrep"
"eza"
"zoxide --locked"
"starship --locked"
)
for tool in "${rust_tools[@]}"; do
log INFO "Installing $tool..."
cargo install $tool
done
# Setup starship configuration
mkdir -p ~/.config
ln -sf ~/linuxbox/config/starship.toml ~/.config/starship.toml
log SUCCESS "Rust tools installed $(show_timer $section_start)"
fi
}
arch_install_embedded_tools() {
if ! role_enabled "CODE" && ! role_enabled "LAB"; then
return 0
fi
log SECTION "Installing embedded development tools"
local section_start=$(date +%s)
if confirm "Install embedded development tools (RP2040, etc.)?"; then
# Add embedded target for Rust
rustup target add thumbv6m-none-eabi
# Install embedded-specific cargo tools
local embedded_tools=(
"elf2uf2-rs --locked"
"probe-run"
"flip-link"
)
for tool in "${embedded_tools[@]}"; do
log INFO "Installing $tool..."
cargo install $tool
done
# Link pico-load script
mkdir -p ~/.local/bin
ln -sf ~/linuxbox/pico-load.sh ~/.local/bin/pico-load
log SUCCESS "Embedded tools installed $(show_timer $section_start)"
fi
}
arch_install_lsp_servers() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
log SECTION "Installing LSP servers"
local section_start=$(date +%s)
if confirm "Install Language Server Protocol servers?"; then
# LSP servers from official repos
local lsp_packages=(
prettier stylua python-black shfmt lua-language-server
bash-language-server ccls vscode-html-languageserver
vscode-json-languageserver marksman pyright yaml-language-server
vscode-css-languageserver clang
)
install_packages "${lsp_packages[@]}"
# LSP servers from AUR
install_aur_packages dockerfile-language-server
# Rust components
rustup component add rust-analyzer clippy rustfmt
# Lua configuration
ln -sf ~/linuxbox/luacheckrc ~/.luacheckrc
log SUCCESS "LSP servers installed $(show_timer $section_start)"
fi
}
arch_install_virtualhere() {
if ! role_enabled "CODE" && ! role_enabled "LAB"; then
return 0
fi
log SECTION "Installing VirtualHere USB client"
local section_start=$(date +%s)
if confirm "Install VirtualHere USB over IP client?"; then
cd ~
# Download VirtualHere client files
local vh_files=(
"virtualhereclient.service"
"vhclientx86_64"
"vhuit64"
)
local vh_base_url="https://www.virtualhere.com/sites/default/files/usbclient"
for file in "${vh_files[@]}"; do
if [ "$file" == "virtualhereclient.service" ]; then
wget "${vh_base_url}/scripts/$file"
else
wget "${vh_base_url}/$file"
fi
done
# Make executables and install
chmod +x ./vhclientx86_64 ./vhuit64
sudo mv ./vhclientx86_64 /usr/sbin
sudo mv ./vhuit64 /usr/sbin
# Setup sudo permissions
echo "$USER ALL=(ALL:ALL) NOPASSWD: /usr/sbin/vhclientx86_64" | \
sudo tee /etc/sudoers.d/$USER+vhclientx86_64
echo "$USER ALL=(ALL:ALL) NOPASSWD: /usr/sbin/vhuit64" | \
sudo tee /etc/sudoers.d/$USER+vhuit64
# Install and enable service
sudo mv virtualhereclient.service /etc/systemd/system/virtualhereclient.service
sudo systemctl daemon-reload
sudo systemctl enable virtualhereclient.service
sudo systemctl start virtualhereclient.service
log SUCCESS "VirtualHere client installed $(show_timer $section_start)"
fi
}
arch_setup_git() {
log SECTION "Setting up Git configuration"
local section_start=$(date +%s)
# Install git-lfs if not present
if ! command_exists git-lfs; then
install_packages git-lfs
fi
# Link git configuration
ln -sf ~/linuxbox/gitconfig ~/.gitconfig
log SUCCESS "Git configuration setup $(show_timer $section_start)"
}
arch_install_lazygit() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
log SECTION "Installing Lazygit"
local section_start=$(date +%s)
if confirm "Install Lazygit Git TUI?"; then
install_packages lazygit
# Setup lazygit configuration
mkdir -p ~/.config/lazygit
ln -sf ~/linuxbox/config/lazygit/config.yml ~/.config/lazygit/config.yml
log SUCCESS "Lazygit installed $(show_timer $section_start)"
fi
}
arch_install_containers() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
log SECTION "Installing container tools"
local section_start=$(date +%s)
if confirm "Install container tools (Docker, Podman)?"; then
# Install from official repositories or AUR
local container_packages=()
if confirm "Install Docker?"; then
container_packages+=(docker docker-compose)
fi
if confirm "Install Podman?"; then
container_packages+=(podman podman-compose)
fi
if [ ${#container_packages[@]} -gt 0 ]; then
install_packages "${container_packages[@]}"
# Add user to docker group if docker was installed
if [[ " ${container_packages[@]} " =~ " docker " ]]; then
sudo usermod -aG docker $USER
log INFO "Added $USER to docker group - logout/login required"
fi
fi
log SUCCESS "Container tools installed $(show_timer $section_start)"
fi
}
# Main function to run all development setup
arch_setup_development() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
log INFO "Development roles not enabled - skipping development setup"
return 0
fi
arch_setup_git
arch_install_development_languages
arch_install_neovim
arch_install_rust_tools
arch_install_embedded_tools
arch_install_lsp_servers
arch_install_virtualhere
arch_install_lazygit
arch_install_containers
}
# Source guard
if [ -z "$ARCH_DEVELOPMENT_LOADED" ]; then
ARCH_DEVELOPMENT_LOADED=true
fi

147
update/arch/gaming.sh Normal file
View File

@ -0,0 +1,147 @@
#!/bin/bash
# Arch Linux Gaming Module
# Handles gaming, VR, and entertainment software
arch_install_gaming_base() {
if ! role_enabled "GAME"; then
return 0
fi
log SECTION "Installing gaming base packages"
local section_start=$(date +%s)
if confirm "Install gaming base (Wine, Steam, etc.)?"; then
local gaming_packages=(
wine wine-mono wine-gecko qt5-tools steam winetricks
onnxruntime mangohud lib32-mangohud gamemode
)
install_packages "${gaming_packages[@]}"
# Gaming tools from AUR
local gaming_aur=(
protonup-qt protontricks lug-helper openmpi jstest-gtk-git
)
install_aur_packages "${gaming_aur[@]}"
log SUCCESS "Gaming base installed $(show_timer $section_start)"
fi
}
arch_install_opentrack() {
if ! role_enabled "GAME"; then
return 0
fi
log SECTION "Installing OpenTrack head tracking"
local section_start=$(date +%s)
if confirm "Build and install OpenTrack?"; then
if [ ! -d ~/Games/opentrack ]; then
mkdir -p ~/Games
cd ~/Games
(
git clone https://github.com/opentrack/opentrack
cd opentrack/
mkdir build
cd build
cmake ..
ccmake .
make
make install
) 2>&1 | tee -a "$LOG_FILE" &
spinner $! "Building OpenTrack (this will take a while)..."
wait
# Create desktop entry
cat > /tmp/opentrack.desktop << EOF
[Desktop Entry]
Version=3.1.0
Type=Application
Name=Opentrack
Exec=$HOME/Games/opentrack/build/install/bin/opentrack -platform xcb
Icon=$HOME/Games/opentrack/contrib/cute-octopus-vector-material_15-1831.jpg
Terminal=false
StartupNotify=true
EOF
sudo mv /tmp/opentrack.desktop /usr/share/applications/opentrack.desktop
sudo update-desktop-database /usr/share/applications
fi
log SUCCESS "OpenTrack installed $(show_timer $section_start)"
fi
}
arch_install_simonbox_gaming() {
if [ "${SYSTEM_INFO[HOSTNAME]}" != "SIMONBOX" ]; then
return 0
fi
log SECTION "Installing SIMONBOX-specific gaming tools"
local section_start=$(date +%s)
if confirm "Install SIMONBOX gaming packages?"; then
# SIMONBOX specific packages
local simonbox_packages=(
fluidsynth gamemode gvfs libayatana-appindicator innoextract
lib32-gamemode lib32-vkd3d python-pefile python-protobuf
vulkan-icd-loader vkd3d lib32-vulkan-icd-loader vulkan-tools
xorg-xgamma umu-launcher lutris
)
install_packages "${simonbox_packages[@]}"
# Sober for Roblox
install_flatpak_apps org.vinegarhq.Sober
log SUCCESS "SIMONBOX gaming setup completed $(show_timer $section_start)"
fi
}
arch_install_vr() {
if ! role_enabled "VR"; then
return 0
fi
log SECTION "Installing VR support"
local section_start=$(date +%s)
if confirm "Install VR tools (Monado, overlays)?"; then
# VR development packages
local vr_packages=(
cli11 glib2-devel nlohmann-json glew
)
install_packages "${vr_packages[@]}"
# VR tools from AUR
local vr_aur=(
monado-vulkan-layers-git wlx-overlay-s-git xrgears envision-xr-git
)
install_aur_packages "${vr_aur[@]}"
log SUCCESS "VR support installed $(show_timer $section_start)"
fi
}
# Main function
arch_setup_gaming() {
if ! role_enabled "GAME"; then
log INFO "Gaming role not enabled - skipping gaming setup"
return 0
fi
arch_install_gaming_base
arch_install_opentrack
arch_install_simonbox_gaming
arch_install_vr
}
if [ -z "$ARCH_GAMING_LOADED" ]; then
ARCH_GAMING_LOADED=true
fi

41
update/arch/lab.sh Normal file
View File

@ -0,0 +1,41 @@
#!/bin/bash
# Arch Linux Lab Equipment Module
arch_install_lab_tools() {
if ! role_enabled "LAB"; then
return 0
fi
log SECTION "Installing lab and measurement tools"
local section_start=$(date +%s)
if confirm "Install lab equipment software?"; then
# PicoScope and related tools from AUR
local lab_aur=(
ps7_libpicoipp ps7_libpicocv picoscope7
ps7_libps2000a ps7_libps3000a
nrf-udev nrfconnect-appimage
)
install_aur_packages "${lab_aur[@]}"
# System packages for lab work
local lab_packages=(tk python-pyserial)
install_packages "${lab_packages[@]}"
# Download SPM6103 viewer
cd ~ && wget -O spm6103_viewer.py \
"https://git.cmtec.se/cm/spm6103_viewer/-/raw/main/spm6103_viewer.py?ref_type=heads&inline=false"
log SUCCESS "Lab tools installed $(show_timer $section_start)"
fi
}
arch_setup_lab() {
arch_install_lab_tools
}
if [ -z "$ARCH_LAB_LOADED" ]; then
ARCH_LAB_LOADED=true
fi

25
update/arch/music.sh Normal file
View File

@ -0,0 +1,25 @@
#!/bin/bash
# Arch Linux Music Production Module
arch_setup_music_production() {
if ! role_enabled "MUSIC"; then
log INFO "Music role not enabled - skipping music production setup"
return 0
fi
log SECTION "Installing music production tools"
local section_start=$(date +%s)
if confirm "Install music production software?"; then
# Music production packages (already handled in system.sh for audio)
# Install Bitwig Studio
install_flatpak_apps com.bitwig.BitwigStudio
log SUCCESS "Music production tools installed $(show_timer $section_start)"
fi
}
if [ -z "$ARCH_MUSIC_LOADED" ]; then
ARCH_MUSIC_LOADED=true
fi

301
update/arch/system.sh Normal file
View File

@ -0,0 +1,301 @@
#!/bin/bash
# Arch Linux System Setup Module
# Handles system packages, drivers, and core system configuration
arch_install_system_base() {
log SECTION "Installing Arch system base packages"
local section_start=$(date +%s)
if confirm "Install essential system packages?"; then
local packages=(
base-devel linux-headers git bc cmake gawk wget gettext unzip curl
inetutils python python-pip python-pipx python-pynvim rustup timeshift
)
install_packages "${packages[@]}"
# Setup Rust
rustup update stable
rustup default stable
log SUCCESS "System base packages installed $(show_timer $section_start)"
fi
}
arch_install_drivers() {
log SECTION "Installing graphics drivers"
local section_start=$(date +%s)
if role_enabled "NVIDIA_GPU" || role_enabled "NVIDIA_1080_GPU"; then
if confirm "Install NVIDIA drivers?"; then
log INFO "Installing NVIDIA drivers..."
# Check if we already have nvidia drivers
local new_kernel="no"
if ! package_installed nvidia-open-dkms && ! package_installed nvidia-dkms; then
new_kernel="yes"
fi
local nvidia_packages=(nvidia-dkms nvidia-utils nvidia-settings opencl-nvidia)
# Add CUDA for high-end GPUs
if role_enabled "NVIDIA_1080_GPU"; then
nvidia_packages+=(cuda)
fi
# Add 32-bit libs for gaming
if role_enabled "GAME"; then
nvidia_packages+=(lib32-nvidia-utils)
fi
install_packages "${nvidia_packages[@]}"
if [ "$new_kernel" == "yes" ]; then
log WARNING "NVIDIA driver updated - kernel rebuild required"
log WARNING "Please reboot and run the script again after reboot"
exit 0
fi
log SUCCESS "NVIDIA drivers installed $(show_timer $section_start)"
fi
else
if confirm "Install Intel graphics drivers?"; then
log INFO "Installing Intel graphics drivers..."
install_packages mesa intel-media-driver
log SUCCESS "Intel drivers installed $(show_timer $section_start)"
fi
fi
}
arch_setup_multilib() {
if role_enabled "GAME"; then
log SECTION "Enabling multilib repository"
if ! grep -q "^\[multilib\]" /etc/pacman.conf; then
if confirm "Enable multilib repository for gaming?"; then
log INFO "Adding multilib repository..."
sudo tee -a /etc/pacman.conf >/dev/null <<EOT
[multilib]
Include = /etc/pacman.d/mirrorlist
EOT
log SUCCESS "Multilib repository enabled"
# Refresh databases after adding multilib
update_package_databases
fi
else
log INFO "Multilib repository already enabled"
fi
fi
}
arch_install_hyprland() {
if ! role_enabled "HYPERLAND"; then
return 0
fi
log SECTION "Installing Hyprland desktop environment"
local section_start=$(date +%s)
if confirm "Install Hyprland desktop environment?"; then
# Core Hyprland packages
local hypr_packages=(
wayvnc nm-connection-editor usbutils plymouth dracut dunst hyprpaper
hypridle hyprland hyprlock xdg-desktop-portal-hyprland polkit-gnome
xorg-xhost gnome-keyring qt6ct gnome-themes-extra qt5-wayland qt6-wayland
lxappearance qt5-tools adwaita-fonts gnome-disk-utility tk
)
install_packages "${hypr_packages[@]}"
# AUR packages for Hyprland
local hypr_aur_packages=(
adwaita-qt5-git adwaita-qt6-git hyprshot walker-bin
)
install_aur_packages "${hypr_aur_packages[@]}"
# Create configuration directories
mkdir -p ~/.config/hypr ~/.local/bin
# Link Hyprland configurations
local hostname="${SYSTEM_INFO[HOSTNAME]}"
if [ -f ~/linuxbox/config/hypr/hyprland_$hostname.conf ]; then
ln -sf ~/linuxbox/config/hypr/hyprland_$hostname.conf ~/.config/hypr/hyprland_extra.conf
else
touch ~/.config/hypr/hyprland_extra.conf
fi
if [ -f ~/linuxbox/config/hypr/hypridle_$hostname.conf ]; then
ln -sf ~/linuxbox/config/hypr/hypridle_$hostname.conf ~/.config/hypr/hypridle.conf
else
ln -sf ~/linuxbox/config/hypr/hypridle.conf ~/.config/hypr/hypridle.conf
fi
# Link main configurations
ln -sf ~/linuxbox/config/hypr/hyprland.conf ~/.config/hypr/hyprland.conf
ln -sf ~/linuxbox/wrappedhl ~/.local/bin/wrappedhl
ln -sf ~/linuxbox/config/hypr/hyprpaper.conf ~/.config/hypr/hyprpaper.conf
# Link theme configurations
ln -sf ~/linuxbox/config/gtk-3.0 ~/.config
ln -sf ~/linuxbox/config/qt5ct ~/.config
ln -sf ~/linuxbox/config/qt6ct ~/.config
ln -sf ~/linuxbox/config/dunst ~/.config
ln -sf ~/linuxbox/config/walker ~/.config
log SUCCESS "Hyprland desktop environment installed $(show_timer $section_start)"
fi
}
arch_install_waybar() {
if ! role_enabled "HYPERLAND"; then
return 0
fi
log SECTION "Installing Waybar"
local section_start=$(date +%s)
if confirm "Install Waybar status bar?"; then
install_packages waybar
mkdir -p ~/.config/waybar
ln -sf ~/linuxbox/config/waybar/config ~/.config/waybar/config
ln -sf ~/linuxbox/config/waybar/style.css ~/.config/waybar/style.css
log SUCCESS "Waybar installed $(show_timer $section_start)"
fi
}
arch_setup_autologin() {
if ! role_enabled "HYPERLAND"; then
return 0
fi
log SECTION "Setting up autologin"
local section_start=$(date +%s)
if confirm "Setup automatic login?"; then
install_aur_packages pam_autologin
sudo /bin/cp -rf ~/linuxbox/login /etc/pam.d/login
sudo /bin/cp -rf ~/linuxbox/getty@.service /usr/lib/systemd/system/getty@.service
sudo touch /etc/security/autologin.conf
log SUCCESS "Autologin configured $(show_timer $section_start)"
fi
}
arch_setup_storage() {
log SECTION "Setting up storage and mounting"
local section_start=$(date +%s)
if confirm "Setup udisks2 for automatic mounting?"; then
install_packages udisks2 udiskie
echo 'ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{UDISKS_FILESYSTEM_SHARED}="1"' | \
sudo tee /lib/udev/rules.d/99-udisks2.rules
echo 'D /media 0755 root root 0 -' | sudo tee /etc/tmpfiles.d/media.conf
# Special configuration for STEAMBOX
if [ "${SYSTEM_INFO[HOSTNAME]}" == "STEAMBOX" ]; then
echo "$USER ALL=(ALL:ALL) NOPASSWD: /usr/sbin/udisksctl mount -b /dev/sda1" | \
sudo tee /etc/sudoers.d/udisksctl
fi
log SUCCESS "Storage setup completed $(show_timer $section_start)"
fi
}
arch_setup_audio() {
log SECTION "Setting up audio system"
local section_start=$(date +%s)
if confirm "Setup PipeWire audio system?"; then
local audio_packages=(pipewire pipewire-pulse pipewire-alsa pavucontrol helvum)
# Add JACK support for music production
if role_enabled "MUSIC"; then
audio_packages+=(pipewire-jack qpwgraph realtime-privileges gamemode)
fi
install_packages "${audio_packages[@]}"
# Setup PipeWire configuration
mkdir -p ~/.config/pipewire
if [ -f ~/linuxbox/config/pipewire/pipewire.conf ]; then
ln -sf ~/linuxbox/config/pipewire/pipewire.conf ~/.config/pipewire/pipewire.conf
fi
# Music production setup
if role_enabled "MUSIC"; then
# Add user to audio groups
sudo usermod -a -G realtime,audio,gamemode $USER
# Setup realtime privileges
sudo tee /etc/security/limits.d/99-pipewire.conf <<'EOF'
@audio soft rtprio 95
@audio soft memlock unlimited
@audio hard rtprio 95
@audio hard memlock unlimited
EOF
# Enable and configure PipeWire services
systemctl --user --now enable pipewire{,-pulse}.{socket,service} filter-chain.service || true
pw-metadata -n settings 0 clock.min-quantum 128 || true
fi
log SUCCESS "Audio system configured $(show_timer $section_start)"
fi
}
arch_install_caffeine() {
if ! role_enabled "HYPERLAND" && ! role_enabled "DESKTOP_BASE"; then
return 0
fi
log SECTION "Installing Caffeine"
local section_start=$(date +%s)
if confirm "Install Caffeine to prevent screen lock?"; then
install_aur_packages caffeine-ng
log SUCCESS "Caffeine installed $(show_timer $section_start)"
fi
}
arch_setup_bluetooth() {
if ! role_enabled "BT"; then
return 0
fi
log SECTION "Setting up Bluetooth"
local section_start=$(date +%s)
if confirm "Setup Bluetooth support?"; then
install_packages bluez bluez-utils blueman
sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service
log SUCCESS "Bluetooth configured $(show_timer $section_start)"
fi
}
# Main function to run all system setup
arch_setup_system() {
arch_install_system_base
arch_setup_multilib
arch_install_drivers
arch_install_hyprland
arch_install_waybar
arch_setup_autologin
arch_setup_storage
arch_setup_audio
arch_install_caffeine
arch_setup_bluetooth
}
# Source guard
if [ -z "$ARCH_SYSTEM_LOADED" ]; then
ARCH_SYSTEM_LOADED=true
fi

245
update/arch/terminal.sh Normal file
View File

@ -0,0 +1,245 @@
#!/bin/bash
# Arch Linux Terminal Utilities Module
# Handles modern CLI tools, terminal applications, and replacements
arch_install_terminal_base() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing terminal base applications"
local section_start=$(date +%s)
if confirm "Install terminal applications (alacritty, tmux, etc.)?"; then
# Remove conflicting fonts
if package_installed gnu-free-fonts; then
sudo pacman --noconfirm -R gnu-free-fonts
fi
local terminal_packages=(
alacritty btop ranger tmux fd ttf-nerd-fonts-symbols
ttf-roboto-mono-nerd gdu bottom dysk
)
install_packages "${terminal_packages[@]}"
log SUCCESS "Terminal base applications installed $(show_timer $section_start)"
fi
}
arch_install_modern_replacements() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing modern CLI replacements"
local section_start=$(date +%s)
if confirm "Install modern CLI tools (already installed via cargo)?"; then
# These are installed via cargo in development.sh
# Just verify they're available and set up aliases
local tools_to_check=("eza" "ripgrep" "fd" "zoxide" "starship")
local missing_tools=()
for tool in "${tools_to_check[@]}"; do
if ! command_exists "$tool"; then
missing_tools+=("$tool")
fi
done
if [ ${#missing_tools[@]} -gt 0 ]; then
log WARNING "Some modern CLI tools are missing: ${missing_tools[*]}"
log INFO "These will be installed via cargo in development setup"
else
log SUCCESS "All modern CLI tools are available"
fi
log SUCCESS "Modern CLI replacements verified $(show_timer $section_start)"
fi
}
arch_install_fzf() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing fzf fuzzy finder"
local section_start=$(date +%s)
if confirm "Install fzf fuzzy finder?"; then
# Clean up any existing installation
rm -rf ~/.fzf
# Clone and install fzf
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install --all
# Source fzf for current session if possible
if [ -f ~/.fzf.bash ]; then
source ~/.fzf.bash
fi
log SUCCESS "fzf installed $(show_timer $section_start)"
fi
}
arch_setup_tmux() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Setting up tmux"
local section_start=$(date +%s)
# tmux is already installed via terminal_packages
# Just link the configuration
ln -sf ~/linuxbox/tmux.conf ~/.tmux.conf
log SUCCESS "tmux configuration linked $(show_timer $section_start)"
}
arch_setup_alacritty() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Setting up Alacritty terminal"
local section_start=$(date +%s)
# Create config directory and link configuration
mkdir -p ~/.config/alacritty
ln -sf ~/linuxbox/config/alacritty/alacritty.toml ~/.config/alacritty/alacritty.toml
log SUCCESS "Alacritty configuration linked $(show_timer $section_start)"
}
arch_setup_shell_config() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Setting up shell configuration"
local section_start=$(date +%s)
# Link bash configuration
ln -sf ~/linuxbox/bashrc_arch ~/.bashrc
# Create local bin directory
mkdir -p ~/.local/bin
# Link utility scripts
ln -sf ~/linuxbox/start_nvim.sh ~/.local/bin/start_nvim
log SUCCESS "Shell configuration setup $(show_timer $section_start)"
}
arch_install_system_monitors() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing system monitoring tools"
local section_start=$(date +%s)
if confirm "Install system monitoring tools (htop, iotop, etc.)?"; then
local monitor_packages=(
htop iotop nethogs bandwhich dust ncdu
)
# Only install packages that aren't already covered by modern replacements
local packages_to_install=()
for pkg in "${monitor_packages[@]}"; do
case "$pkg" in
"dust"|"ncdu")
# These might conflict with modern versions, check first
if ! command_exists "$pkg"; then
packages_to_install+=("$pkg")
fi
;;
*)
packages_to_install+=("$pkg")
;;
esac
done
if [ ${#packages_to_install[@]} -gt 0 ]; then
install_packages "${packages_to_install[@]}"
fi
log SUCCESS "System monitoring tools installed $(show_timer $section_start)"
fi
}
arch_install_network_tools() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing network utilities"
local section_start=$(date +%s)
if confirm "Install network tools (wget, curl, etc.)?"; then
local network_packages=(
wget curl rsync openssh bind-tools whois nmap
)
install_packages "${network_packages[@]}"
log SUCCESS "Network tools installed $(show_timer $section_start)"
fi
}
arch_install_archive_tools() {
if ! role_enabled "TERMINAL"; then
return 0
fi
log SECTION "Installing archive and compression tools"
local section_start=$(date +%s)
if confirm "Install archive tools (zip, 7zip, etc.)?"; then
local archive_packages=(
zip unzip p7zip tar gzip bzip2 xz
)
install_packages "${archive_packages[@]}"
log SUCCESS "Archive tools installed $(show_timer $section_start)"
fi
}
arch_setup_locale() {
log SECTION "Setting up system locale"
local section_start=$(date +%s)
# Set locale
sudo localectl set-locale LANG=en_US.UTF-8
log SUCCESS "System locale configured $(show_timer $section_start)"
}
# Main function to run all terminal setup
arch_setup_terminal() {
if ! role_enabled "TERMINAL"; then
log INFO "Terminal role not enabled - skipping terminal setup"
return 0
fi
arch_setup_locale
arch_install_terminal_base
arch_install_modern_replacements
arch_install_fzf
arch_setup_tmux
arch_setup_alacritty
arch_setup_shell_config
arch_install_system_monitors
arch_install_network_tools
arch_install_archive_tools
}
# Source guard
if [ -z "$ARCH_TERMINAL_LOADED" ]; then
ARCH_TERMINAL_LOADED=true
fi

View File

@ -0,0 +1,55 @@
# Arch Linux Role Configuration
# This file defines role assignments for Arch Linux systems
# Default roles for all Arch systems
DEFAULT_ROLES=(
"TERMINAL"
)
# Hostname-specific role assignments
configure_roles_for_hostname() {
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"
;;
*)
# Default configuration for unknown hostnames
ROLES[TERMINAL]="yes"
if supports_feature "desktop"; then
ROLES[DESKTOP_BASE]="yes"
fi
;;
esac
}

View File

@ -0,0 +1,44 @@
# Ubuntu Linux Role Configuration
# This file defines role assignments for Ubuntu Linux systems
# Default roles for all Ubuntu systems
DEFAULT_ROLES=(
"DEVELOPMENT"
"TERMINAL"
)
# Hostname-specific role assignments
configure_roles_for_hostname() {
local hostname="$1"
case "$hostname" in
"CMBOX"|"LABBOX"|"STEAMBOX"|"SIMONBOX")
# These are primarily Arch systems, but provide fallback Ubuntu config
ROLES[DEVELOPMENT]="yes"
ROLES[TERMINAL]="yes"
if [ "${SYSTEM_INFO[WSL]}" != "yes" ] && supports_feature "desktop"; then
ROLES[DESKTOP_BASE]="yes"
fi
;;
*)
# Default configuration for Ubuntu systems
ROLES[DEVELOPMENT]="yes"
ROLES[TERMINAL]="yes"
# Enable desktop roles if not in WSL and desktop is available
if [ "${SYSTEM_INFO[WSL]}" != "yes" ] && supports_feature "desktop"; then
ROLES[DESKTOP_BASE]="yes"
fi
# Enable WSL-specific roles if in WSL
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
ROLES[WSL]="yes"
fi
# Enable Bluetooth if available
if supports_feature "bluetooth"; then
ROLES[BT]="yes"
fi
;;
esac
}

419
update/lib/core.sh Normal file
View File

@ -0,0 +1,419 @@
#!/bin/bash
# CMtec Enhanced Update System - Core Library
# Shared functions for logging, UI, health checks, and utilities
VERSION="3.0.0"
LOG_FILE="/tmp/update_$(date +%Y%m%d_%H%M%S).log"
START_TIME=$(date +%s)
INTERACTIVE=false
# Color definitions and Unicode symbols
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
GRAY='\033[0;37m'
BOLD='\033[1m'
RESET='\033[0m'
# Unicode symbols
CHECK="✓"
CROSS="✗"
WARNING="⚠"
INFO=""
ROCKET="🚀"
GEAR="⚙"
TIMER="⏱"
PACKAGE="📦"
# Initialize core variables
declare -A ROLES
declare -A SYSTEM_INFO
# Logging function with colored output
log() {
local level=$1
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
case $level in
ERROR) echo -e "${RED}${CROSS}${RESET} $message" ;;
SUCCESS) echo -e "${GREEN}${CHECK}${RESET} $message" ;;
WARNING) echo -e "${YELLOW}${WARNING}${RESET} $message" ;;
INFO) echo -e "${BLUE}${INFO}${RESET} $message" ;;
SECTION) echo -e "\n${CYAN}${GEAR} $message${RESET}" ;;
*) echo -e "${GRAY}$message${RESET}" ;;
esac
}
# Fancy spinner function for long operations
spinner() {
local pid=$1
local message="$2"
local delay=0.08
local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
echo -e "${CYAN}${GEAR} $message${RESET}"
printf " "
while kill -0 $pid 2>/dev/null; do
local temp=${spinstr#?}
printf "${BLUE}%c${RESET}" "$spinstr"
spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b"
done
printf "${GREEN}${CHECK}${RESET}\n"
}
# Progress bar function
progress_bar() {
local current=$1
local total=$2
local message="$3"
local width=40
local percentage=$((current * 100 / total))
local filled=$((current * width / total))
local empty=$((width - filled))
printf "\r${message} ${BLUE}["
printf "%*s" $filled | tr ' ' '█'
printf "%*s" $empty | tr ' ' '░'
printf "] %d%% (%d/%d)${RESET}" $percentage $current $total
if [ $current -eq $total ]; then
echo
fi
}
# Timer function
show_timer() {
local start_time=$1
local end_time=$(date +%s)
local elapsed=$((end_time - start_time))
local hours=$((elapsed / 3600))
local minutes=$(((elapsed % 3600) / 60))
local seconds=$((elapsed % 60))
if [ $hours -gt 0 ]; then
printf "${CYAN}${TIMER} %02d:%02d:%02d${RESET}" $hours $minutes $seconds
else
printf "${CYAN}${TIMER} %02dm %02ds${RESET}" $minutes $seconds
fi
}
# Confirmation function for interactive mode
confirm() {
if [ "$INTERACTIVE" == "true" ]; then
local prompt="$1"
local default="${2:-n}"
echo -ne "${YELLOW}${WARNING} $prompt [y/N]: ${RESET}"
read -r response
response=${response:-$default}
case $response in
[yY][eE][sS]|[yY]) return 0 ;;
*) return 1 ;;
esac
else
return 0
fi
}
# System health check function
system_health_check() {
local section_start=$(date +%s)
log SECTION "Running system health check"
local issues=0
# Check disk space
local root_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$root_usage" -gt 85 ]; then
log WARNING "Root filesystem is ${root_usage}% full"
((issues++))
else
log SUCCESS "Root filesystem usage: ${root_usage}%"
fi
# Check available memory
local mem_available=$(free -m | awk 'NR==2{printf "%d", $7}')
if [ "$mem_available" -lt 512 ]; then
log WARNING "Low memory available: ${mem_available}MB"
((issues++))
else
log SUCCESS "Available memory: ${mem_available}MB"
fi
# Check for failed systemd services
local failed_services=$(systemctl --failed --quiet --no-legend 2>/dev/null | wc -l)
if [ "$failed_services" -gt 0 ]; then
log WARNING "$failed_services failed systemd services detected"
((issues++))
else
log SUCCESS "All systemd services running normally"
fi
# Check package manager locks (distro-specific)
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
if [ -f /var/lib/pacman/db.lck ]; then
log WARNING "Pacman database is locked"
((issues++))
fi
;;
"ubuntu"|"debian")
if sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; then
log WARNING "APT database is locked"
((issues++))
fi
;;
esac
if [ $issues -eq 0 ]; then
log SUCCESS "System health check passed $(show_timer $section_start)"
else
log WARNING "System health check found $issues issues $(show_timer $section_start)"
if [ "$INTERACTIVE" == "true" ]; then
if ! confirm "Continue despite health issues?"; then
log INFO "Update cancelled by user due to health issues"
exit 1
fi
fi
fi
return $issues
}
# Error handler function
error_handler() {
local line_number=$1
local error_code=$2
local command="$3"
log ERROR "Script failed at line $line_number with exit code $error_code"
log ERROR "Failed command: $command"
log ERROR "Check log file: $LOG_FILE"
echo -e "\n${RED}╔══════════════════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${RED}${RESET} ${BOLD}SCRIPT FAILED${RESET} ${RED}${RESET}"
echo -e "${RED}╠══════════════════════════════════════════════════════════════════════════╣${RESET}"
echo -e "${RED}${RESET} Line: $line_number ${RED}${RESET}"
echo -e "${RED}${RESET} Exit Code: $error_code ${RED}${RESET}"
echo -e "${RED}${RESET} Log File: $LOG_FILE ${RED}${RESET}"
echo -e "${RED}╚══════════════════════════════════════════════════════════════════════════╝${RESET}\n"
exit $error_code
}
# Fancy header display with original ASCII art
show_header() {
local hostname=$1
local distro=$2
clear
echo -e "\n${BLUE}╔══════════════════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}.${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ \\${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ \\${RESET} ${WHITE} # ${BLUE}| *${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/^. \\${RESET} ${WHITE} a##e #%\" a#\"e 6##% ${BLUE}| | |-^-. | | \\ /${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ .-. \\${RESET} ${WHITE}.oOo# # # # # ${BLUE}| | | | | | X${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ ( ) _\\${RESET} ${WHITE}%OoO# # %#e\" # # ${BLUE}| | | | ^._.| / \\${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ _.~ ~._^\\${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/.^ ^\\ ${GRAY}${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${GREEN}${ROCKET} CMtec Universal Update System v$VERSION${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${GRAY}$hostname | $distro | $(date '+%Y-%m-%d %H:%M:%S')${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════════════════════════╝${RESET}\n"
}
# Alternative fancy header with original Arch-style ASCII art
show_arch_header() {
local hostname=$1
clear
echo -e "\n${BLUE}╔══════════════════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}.${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ \\${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ \\${RESET} ${WHITE} # ${BLUE}| *${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/^. \\${RESET} ${WHITE} a##e #%\" a#\"e 6##% ${BLUE}| | |-^-. | | \\ /${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ .-. \\${RESET} ${WHITE}.oOo# # # # # ${BLUE}| | | | | | X${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ ( ) _\\${RESET} ${WHITE}%OoO# # %#e\" # # ${BLUE}| | | | ^._.| / \\${RESET} ${GRAY}${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/ _.~ ~._^\\${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}/.^ ^\\ ${GRAY}${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${GREEN}${ROCKET} CMtec '$hostname' Enhanced Update Script${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}${RESET} ${GRAY}$(date '+%Y-%m-%d %H:%M:%S')${RESET} ${BLUE}${RESET}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════════════════════════╝${RESET}\n"
}
# Ubuntu-style header with Ubuntu ASCII art
show_ubuntu_header() {
local hostname=$1
clear
echo -e "\n${YELLOW}╔══════════════════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${YELLOW}${RESET} ${RED} .--.${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} .-\"''\`(|||)${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} ,\`\\ \\ \`-\`.${RESET} 88 88 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} / \\ \"\`\`-. \`${RESET} 88 88 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} .-. , \`___:${RESET} 88 88 88,888, 88 88 ,88888, 88888 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} (:::) : ___ ${RESET} 88 88 88 88 88 88 88 88 88 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} \`-\` \` , :${RESET} 88 88 88 88 88 88 88 88 88 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} \\ / ,..-\` ,${RESET} 88 88 88 88 88 88 88 88 88 ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} \`.\/ / .-.\`${RESET} \"88888\" \"88888\" \"88888\" 88 88 \"8888${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} \`-..-( )${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${RED} \`-\`${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${GREEN}${ROCKET} CMtec Ubuntu Install/Update Script${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}${RESET} ${GRAY}$hostname | $(date '+%Y-%m-%d %H:%M:%S')${RESET} ${YELLOW}${RESET}"
echo -e "${YELLOW}╚══════════════════════════════════════════════════════════════════════════╝${RESET}\n"
}
# Display enabled roles with fancy formatting
show_roles() {
local role_count=0
for role in "${!ROLES[@]}"; do
if [ "${ROLES[$role]}" == "yes" ]; then
((role_count++))
fi
done
if [ $role_count -eq 0 ]; then
log WARNING "No roles enabled"
return
fi
log SECTION "System Configuration"
echo -e "${BOLD}${PACKAGE} Enabled Roles ($role_count total):${RESET}"
for role in "${!ROLES[@]}"; do
if [ "${ROLES[$role]}" == "yes" ]; then
case $role in
desktop*|DESKTOP*) icon="🖥️" ;;
game*|GAME*) icon="🎮" ;;
music*|MUSIC*) icon="🎵" ;;
dev*|code*|DEV*|CODE*) icon="💻" ;;
terminal*|TERMINAL*) icon="📟" ;;
nvidia*|NVIDIA*) icon="🎯" ;;
vr*|VR*) icon="🥽" ;;
lab*|LAB*) icon="🔬" ;;
bt*|BT*|bluetooth*) icon="📶" ;;
hypr*|HYPERLAND*) icon="🌊" ;;
wsl*|WSL*) icon="🐧" ;;
*) icon="⚙️" ;;
esac
echo -e " ${CYAN}$icon $role${RESET}"
fi
done
echo
}
# Final summary with statistics
show_final_summary() {
local end_time=$(date +%s)
local total_time=$((end_time - START_TIME))
local total_hours=$((total_time / 3600))
local total_minutes=$(((total_time % 3600) / 60))
local total_seconds=$((total_time % 60))
# Collect system info for summary
local kernel_version=$(uname -r)
local role_count=0
for role in "${!ROLES[@]}"; do
if [ "${ROLES[$role]}" == "yes" ]; then
((role_count++))
fi
done
log SECTION "Update Summary"
echo -e "\n${GREEN}╔══════════════════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${GREEN}${RESET} ${BOLD}🎉 UPDATE COMPLETE! 🎉${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}╠══════════════════════════════════════════════════════════════════════════╣${RESET}"
echo -e "${GREEN}${RESET} ${CYAN}📊 Statistics:${RESET} ${GREEN}${RESET}"
if [ $total_hours -gt 0 ]; then
echo -e "${GREEN}${RESET} • Total time: ${CYAN}${TIMER} ${total_hours}h ${total_minutes}m ${total_seconds}s${RESET} ${GREEN}${RESET}"
else
echo -e "${GREEN}${RESET} • Total time: ${CYAN}${TIMER} ${total_minutes}m ${total_seconds}s${RESET} ${GREEN}${RESET}"
fi
echo -e "${GREEN}${RESET} • Hostname: ${CYAN}${SYSTEM_INFO[HOSTNAME]}${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} • Distro: ${CYAN}${SYSTEM_INFO[DISTRO]} ${SYSTEM_INFO[VERSION]}${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} • Kernel: ${CYAN}$kernel_version${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} • Active roles: ${CYAN}$role_count enabled${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} • Log file: ${GRAY}$LOG_FILE${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}╠══════════════════════════════════════════════════════════════════════════╣${RESET}"
echo -e "${GREEN}${RESET} ${YELLOW}⚠️ SYSTEM REBOOT RECOMMENDED ⚠️${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}${RESET} ${WHITE}Some updates may require a reboot to take effect${RESET} ${GREEN}${RESET}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════════════════╝${RESET}\n"
log SUCCESS "Update script completed successfully"
log INFO "Total execution time: $(show_timer $START_TIME)"
log INFO "System: ${SYSTEM_INFO[DISTRO]} ${SYSTEM_INFO[VERSION]} on ${SYSTEM_INFO[HOSTNAME]}"
log INFO "Active roles: $role_count"
# Interactive reboot prompt
if [ "$INTERACTIVE" == "true" ]; then
echo -ne "${YELLOW}${WARNING} Reboot system now? [y/N]: ${RESET}"
read -r -t 10 response || response="n"
case $response in
[yY][eE][sS]|[yY])
log INFO "Rebooting system as requested by user"
echo -e "${GREEN}${CHECK} Rebooting in 3 seconds...${RESET}"
sleep 1
echo -e "${GREEN}${CHECK} Rebooting in 2 seconds...${RESET}"
sleep 1
echo -e "${GREEN}${CHECK} Rebooting in 1 second...${RESET}"
sleep 1
sudo reboot
;;
*)
log INFO "Reboot cancelled by user"
echo -e "${BLUE}${INFO} Remember to reboot when convenient!${RESET}"
;;
esac
else
echo -e "${BLUE}${INFO} Please reboot your system when convenient${RESET}"
fi
echo -e "${GREEN}${CHECK} Thank you for using CMtec Universal Update System!${RESET}\n"
}
# Utility function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Utility function to check if package is installed (distro-agnostic)
package_installed() {
local package="$1"
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
pacman -Qs "$package" >/dev/null 2>&1
;;
"ubuntu"|"debian")
dpkg -l "$package" >/dev/null 2>&1
;;
*)
return 1
;;
esac
}
# Initialize logging
init_core() {
# Set error trap
trap 'error_handler ${LINENO} $? "$BASH_COMMAND"' ERR
# Initialize log
log INFO "Starting CMtec Universal Update System v$VERSION"
log INFO "Log file: $LOG_FILE"
log INFO "Interactive mode: $INTERACTIVE"
}
# Source guard to prevent double-sourcing
if [ -z "$CORE_LIB_LOADED" ]; then
CORE_LIB_LOADED=true
fi

266
update/lib/detect.sh Normal file
View File

@ -0,0 +1,266 @@
#!/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

406
update/lib/packages.sh Normal file
View File

@ -0,0 +1,406 @@
#!/bin/bash
# CMtec Update System - Package Management Abstraction Layer
# Provides unified interface for different package managers
# Package manager detection and initialization
init_package_managers() {
log INFO "Initializing package managers for ${SYSTEM_INFO[DISTRO]}..."
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
PACKAGE_MANAGER="pacman"
AUR_HELPER=""
detect_aur_helper
FLATPAK_AVAILABLE=$(command_exists flatpak && echo "yes" || echo "no")
;;
"ubuntu"|"debian")
PACKAGE_MANAGER="apt"
SNAP_AVAILABLE=$(command_exists snap && echo "yes" || echo "no")
FLATPAK_AVAILABLE=$(command_exists flatpak && echo "yes" || echo "no")
;;
*)
log ERROR "Unsupported distribution: ${SYSTEM_INFO[DISTRO]}"
return 1
;;
esac
log SUCCESS "Package managers initialized"
log INFO "Primary: $PACKAGE_MANAGER"
[ -n "$AUR_HELPER" ] && log INFO "AUR helper: $AUR_HELPER"
[ "$FLATPAK_AVAILABLE" == "yes" ] && log INFO "Flatpak: available"
[ "$SNAP_AVAILABLE" == "yes" ] && log INFO "Snap: available"
}
# Detect AUR helper for Arch systems
detect_aur_helper() {
local helpers=("yay" "paru" "pikaur" "trizen")
for helper in "${helpers[@]}"; do
if command_exists "$helper"; then
AUR_HELPER="$helper"
log INFO "Found AUR helper: $helper"
return 0
fi
done
log WARNING "No AUR helper found - will install yay if needed"
AUR_HELPER=""
}
# Install AUR helper (yay) if not present
install_aur_helper() {
if [ -n "$AUR_HELPER" ]; then
return 0
fi
log INFO "Installing yay AUR helper..."
local section_start=$(date +%s)
# Clean up any existing build directory
[ -d ~/yay-bin ] && rm -rf ~/yay-bin
cd ~
(
git clone https://aur.archlinux.org/yay-bin.git 2>&1 | tee -a "$LOG_FILE"
cd yay-bin
makepkg --noconfirm -si 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing yay AUR helper..."
wait
# Clean up build directory
[ -d ~/yay-bin ] && rm -rf ~/yay-bin
AUR_HELPER="yay"
log SUCCESS "Yay AUR helper installed $(show_timer $section_start)"
}
# Update package databases
update_package_databases() {
local section_start=$(date +%s)
log SECTION "Updating package databases"
case "$PACKAGE_MANAGER" in
"pacman")
if confirm "Refresh pacman package databases?"; then
(
sudo pacman -Syy --noconfirm 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Refreshing pacman databases..."
wait
log SUCCESS "Pacman databases updated $(show_timer $section_start)"
else
log WARNING "Package database refresh skipped"
fi
;;
"apt")
if confirm "Update APT package databases?"; then
(
sudo apt update 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating APT databases..."
wait
log SUCCESS "APT databases updated $(show_timer $section_start)"
else
log WARNING "Package database update skipped"
fi
;;
esac
}
# System upgrade
system_upgrade() {
local section_start=$(date +%s)
log SECTION "Upgrading system packages"
case "$PACKAGE_MANAGER" in
"pacman")
if confirm "Upgrade all system packages?"; then
(
sudo pacman -Su --noconfirm 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Upgrading system packages (may take a while)..."
wait
log SUCCESS "System packages upgraded $(show_timer $section_start)"
else
log WARNING "System upgrade skipped"
fi
;;
"apt")
if confirm "Upgrade all system packages?"; then
(
sudo apt upgrade -y 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Upgrading system packages (may take a while)..."
wait
log SUCCESS "System packages upgraded $(show_timer $section_start)"
else
log WARNING "System upgrade skipped"
fi
;;
esac
}
# Install packages using primary package manager
install_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ]; then
return 0
fi
log INFO "Installing packages: ${packages[*]}"
case "$PACKAGE_MANAGER" in
"pacman")
(
sudo pacman --noconfirm --needed -S "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} packages..."
wait
;;
"apt")
(
sudo apt install -y "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} packages..."
wait
;;
esac
}
# Install AUR packages (Arch only)
install_aur_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ] || [ "$PACKAGE_MANAGER" != "pacman" ]; then
return 0
fi
# Ensure AUR helper is available
if [ -z "$AUR_HELPER" ]; then
install_aur_helper
fi
log INFO "Installing AUR packages: ${packages[*]}"
(
"$AUR_HELPER" --noconfirm -S --needed --aur "${packages[@]}" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing ${#packages[@]} AUR packages..."
wait
}
# Update AUR packages
update_aur_packages() {
if [ "$PACKAGE_MANAGER" != "pacman" ] || [ -z "$AUR_HELPER" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating AUR packages"
if confirm "Update AUR packages?"; then
(
"$AUR_HELPER" --noconfirm --aur 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating AUR packages..."
wait
log SUCCESS "AUR packages updated $(show_timer $section_start)"
else
log WARNING "AUR update skipped"
fi
}
# Install Flatpak applications
install_flatpak_apps() {
local apps=("$@")
if [ ${#apps[@]} -eq 0 ] || [ "$FLATPAK_AVAILABLE" != "yes" ]; then
return 0
fi
log INFO "Installing Flatpak apps: ${apps[*]}"
for app in "${apps[@]}"; do
(
flatpak install -y flathub "$app" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Flatpak app: $app..."
wait
done
}
# Update Flatpak applications
update_flatpak_apps() {
if [ "$FLATPAK_AVAILABLE" != "yes" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating Flatpak applications"
if confirm "Update Flatpak applications?"; then
(
flatpak update -y 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating Flatpak applications..."
wait
log SUCCESS "Flatpak applications updated $(show_timer $section_start)"
else
log WARNING "Flatpak update skipped"
fi
}
# Install Snap packages (Ubuntu/Debian)
install_snap_packages() {
local packages=("$@")
if [ ${#packages[@]} -eq 0 ] || [ "$SNAP_AVAILABLE" != "yes" ]; then
return 0
fi
log INFO "Installing Snap packages: ${packages[*]}"
for package in "${packages[@]}"; do
local snap_args=""
# Handle special snap flags
case "$package" in
*"--classic")
snap_args="--classic"
package=${package//" --classic"/}
;;
esac
(
sudo snap install $snap_args "$package" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Snap package: $package..."
wait
done
}
# Update Snap packages
update_snap_packages() {
if [ "$SNAP_AVAILABLE" != "yes" ]; then
return 0
fi
local section_start=$(date +%s)
log SECTION "Updating Snap packages"
if confirm "Update Snap packages?"; then
(
sudo snap refresh 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Updating Snap packages..."
wait
log SUCCESS "Snap packages updated $(show_timer $section_start)"
else
log WARNING "Snap update skipped"
fi
}
# Install packages from various sources (unified interface)
install_package_set() {
local pkg_type="$1"
shift
local packages=("$@")
if [ ${#packages[@]} -eq 0 ]; then
return 0
fi
case "$pkg_type" in
"system"|"main")
install_packages "${packages[@]}"
;;
"aur")
install_aur_packages "${packages[@]}"
;;
"flatpak")
install_flatpak_apps "${packages[@]}"
;;
"snap")
install_snap_packages "${packages[@]}"
;;
*)
log ERROR "Unknown package type: $pkg_type"
return 1
;;
esac
}
# Setup package managers (install if needed)
setup_package_managers() {
log SECTION "Setting up package managers"
# Setup Flatpak if not available but potentially useful
if [ "$FLATPAK_AVAILABLE" != "yes" ] && [ "${SYSTEM_INFO[WSL]}" != "yes" ]; then
setup_flatpak
fi
# Setup Snap for Ubuntu systems if not available
if [ "$PACKAGE_MANAGER" == "apt" ] && [ "$SNAP_AVAILABLE" != "yes" ]; then
setup_snap
fi
# Install AUR helper for Arch if needed
if [ "$PACKAGE_MANAGER" == "pacman" ] && [ -z "$AUR_HELPER" ]; then
install_aur_helper
fi
}
# Setup Flatpak
setup_flatpak() {
log INFO "Setting up Flatpak..."
local section_start=$(date +%s)
(
case "$PACKAGE_MANAGER" in
"pacman")
sudo pacman --noconfirm --needed -S flatpak
;;
"apt")
sudo apt install -y flatpak
;;
esac
# Add Flathub repository
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Install Flatseal for permission management
flatpak install -y flathub com.github.tchx84.Flatseal
) 2>&1 | tee -a "$LOG_FILE" &
spinner $! "Setting up Flatpak and Flathub repository..."
wait
FLATPAK_AVAILABLE="yes"
log SUCCESS "Flatpak setup completed $(show_timer $section_start)"
}
# Setup Snap
setup_snap() {
log INFO "Setting up Snap..."
local section_start=$(date +%s)
(
sudo apt install -y snap 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Installing Snap package manager..."
wait
SNAP_AVAILABLE="yes"
log SUCCESS "Snap setup completed $(show_timer $section_start)"
}
# Get package manager status
get_package_manager_status() {
echo "Primary: $PACKAGE_MANAGER"
[ -n "$AUR_HELPER" ] && echo "AUR: $AUR_HELPER"
[ "$FLATPAK_AVAILABLE" == "yes" ] && echo "Flatpak: available"
[ "$SNAP_AVAILABLE" == "yes" ] && echo "Snap: available"
}
# Source guard to prevent double-sourcing
if [ -z "$PACKAGES_LIB_LOADED" ]; then
PACKAGES_LIB_LOADED=true
fi

332
update/lib/roles.sh Normal file
View File

@ -0,0 +1,332 @@
#!/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

View File

@ -0,0 +1,146 @@
#!/bin/bash
# Ubuntu Development Environment Module
ubuntu_install_rust() {
log SECTION "Installing Rust toolchain"
local section_start=$(date +%s)
if confirm "Install Rust via rustup?"; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --no-modify-path -y
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
source "$HOME/.cargo/env"
fi
rustup self update
rustup update stable
rustup default stable
log SUCCESS "Rust installed $(show_timer $section_start)"
fi
}
ubuntu_install_node() {
log SECTION "Installing Node.js"
local section_start=$(date +%s)
if confirm "Install Node.js?"; then
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
install_packages nodejs
npm config set prefix "${HOME}/.npm"
log SUCCESS "Node.js installed $(show_timer $section_start)"
fi
}
ubuntu_install_python() {
log SECTION "Setting up Python development"
local section_start=$(date +%s)
local version="${SYSTEM_INFO[VERSION]}"
if [ "$version" == "22.04" ]; then
pip3 install pynvim
else
install_packages python3-pynvim
fi
log SUCCESS "Python development setup $(show_timer $section_start)"
}
ubuntu_build_neovim() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
log SECTION "Building Neovim from source"
local section_start=$(date +%s)
if confirm "Build Neovim from source?"; then
# Remove system neovim if in WSL
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
sudo apt -y purge --auto-remove neovim
fi
install_packages bat fd-find
cd ~
if [ -d ~/neovim ]; then rm -rf ~/neovim; fi
(
git clone https://github.com/neovim/neovim
cd neovim && git checkout stable
make CMAKE_BUILD_TYPE=RelWithDebInfo
cd build && cpack -G DEB && sudo dpkg -i nvim*.deb
) 2>&1 | tee -a "$LOG_FILE" &
spinner $! "Building Neovim (this will take a while)..."
wait
if [ -d ~/neovim ]; then rm -rf ~/neovim; fi
mkdir -p ~/.config/nvim
ln -sf ~/linuxbox/config/nvim/init.lua ~/.config/nvim/init.lua
log SUCCESS "Neovim built and installed $(show_timer $section_start)"
fi
}
ubuntu_install_languages() {
log SECTION "Installing programming languages"
local section_start=$(date +%s)
if confirm "Install additional languages (Go, PHP, Ruby, etc.)?"; then
local packages=(golang ruby ruby-dev php php-curl php-xml php-mbstring luarocks composer)
install_packages "${packages[@]}"
# Java installation
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
sudo add-apt-repository -y ppa:linuxuprising/java
sudo apt update
install_packages oracle-java17-installer
else
install_packages default-jdk
fi
log SUCCESS "Programming languages installed $(show_timer $section_start)"
fi
}
ubuntu_install_julia() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
log SECTION "Installing Julia"
local section_start=$(date +%s)
if confirm "Install Julia programming language?"; then
cd ~
wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/julia-1.9.0-linux-x86_64.tar.gz
tar -xvzf julia-1.9.0-linux-x86_64.tar.gz
sudo cp -r julia-1.9.0 /opt/
sudo ln -sf /opt/julia-1.9.0/bin/julia /usr/local/bin/julia
rm julia-1.9.0-linux-x86_64.tar.gz*
rm -rf julia-1.9.0
log SUCCESS "Julia installed $(show_timer $section_start)"
fi
}
ubuntu_setup_development() {
if ! role_enabled "CODE" && ! role_enabled "DEVELOPMENT"; then
return 0
fi
ubuntu_install_rust
ubuntu_install_node
ubuntu_install_python
ubuntu_build_neovim
ubuntu_install_languages
ubuntu_install_julia
}
if [ -z "$UBUNTU_DEVELOPMENT_LOADED" ]; then
UBUNTU_DEVELOPMENT_LOADED=true
fi

75
update/ubuntu/system.sh Normal file
View File

@ -0,0 +1,75 @@
#!/bin/bash
# Ubuntu Linux System Setup Module
ubuntu_install_system_base() {
log SECTION "Installing Ubuntu system base packages"
local section_start=$(date +%s)
if confirm "Install essential system packages?"; then
local packages=(
build-essential gawk imagemagick gpg ninja-build gettext cmake unzip curl
libssl-dev libffi-dev file libudev-dev pkg-config locales btop ncdu
ranger timeshift python3 python3-pip python3-venv python3-dev pipx
)
install_packages "${packages[@]}"
log SUCCESS "System base packages installed $(show_timer $section_start)"
fi
}
ubuntu_install_homebrew() {
log SECTION "Installing Homebrew"
local section_start=$(date +%s)
if confirm "Install Homebrew package manager?"; then
export NONINTERACTIVE=1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
BREW_PREFIX="/home/linuxbrew/.linuxbrew"
if [ -d "$BREW_PREFIX" ]; then
eval "$("$BREW_PREFIX"/bin/brew shellenv)"
log SUCCESS "Homebrew installed $(show_timer $section_start)"
else
log ERROR "Homebrew installation failed"
return 1
fi
fi
}
ubuntu_setup_locale() {
log SECTION "Setting up locale"
sudo locale-gen "en_US.UTF-8"
sudo update-locale LANG=en_US.UTF-8
}
ubuntu_setup_shell_config() {
log SECTION "Setting up shell configuration"
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
ln -sf ~/linuxbox/bashrc_ubuntu ~/.bashrc
ln -sf ~/linuxbox/gitconfig.work ~/.gitconfig
else
ln -sf ~/linuxbox/bashrc_ubuntu ~/.bashrc
ln -sf ~/linuxbox/gitconfig ~/.gitconfig
mkdir -p ~/.config/alacritty
ln -sf ~/linuxbox/config/alacritty/alacritty.toml ~/.config/alacritty/alacritty.toml
fi
mkdir -p ~/.local/bin
ln -sf ~/linuxbox/update_wrapper.sh ~/.local/bin/update
ln -sf ~/linuxbox/start_nvim.sh ~/.local/bin/start_nvim
ln -sf ~/linuxbox/start_toolbox.sh ~/.local/bin/start_toolbox
}
ubuntu_setup_system() {
ubuntu_setup_locale
ubuntu_install_system_base
ubuntu_install_homebrew
ubuntu_setup_shell_config
}
if [ -z "$UBUNTU_SYSTEM_LOADED" ]; then
UBUNTU_SYSTEM_LOADED=true
fi

29
update/ubuntu/ubuntu.sh Normal file
View File

@ -0,0 +1,29 @@
#!/bin/bash
# Ubuntu Linux Master Module
# Loads all Ubuntu-specific modules and orchestrates installation
# Source all Ubuntu modules
source "$SCRIPT_DIR/ubuntu/system.sh"
source "$SCRIPT_DIR/ubuntu/development.sh"
# Main Ubuntu installation function
ubuntu_install_all() {
log SECTION "Starting Ubuntu Linux installation"
# System setup (homebrew, base packages)
ubuntu_setup_system
# Development environment (custom builds, languages)
ubuntu_setup_development
# Note: Terminal, desktop, etc. would be added here
# For now, focusing on the core differences
log SUCCESS "Ubuntu Linux installation completed"
}
# Source guard
if [ -z "$UBUNTU_MASTER_LOADED" ]; then
UBUNTU_MASTER_LOADED=true
fi

193
update/update.sh Executable file
View File

@ -0,0 +1,193 @@
#!/bin/bash
# CMtec Universal Update System v3.0.0
# Main entry point for cross-platform system updates
set -e
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Parse command line arguments
INTERACTIVE=false
HELP=false
while [[ $# -gt 0 ]]; do
case $1 in
-i|--interactive)
INTERACTIVE=true
shift
;;
-h|--help)
HELP=true
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [-i|--interactive] [-h|--help]"
exit 1
;;
esac
done
if [ "$HELP" == "true" ]; then
echo "CMtec Universal Update System v3.0.0"
echo ""
echo "Usage: $0 [OPTIONS]"
echo ""
echo "OPTIONS:"
echo " -i, --interactive Enable interactive mode with confirmations"
echo " -h, --help Show this help message"
echo ""
echo "This script automatically detects your Linux distribution and applies"
echo "appropriate updates and software installations based on system roles."
exit 0
fi
# Source all library files
source "$SCRIPT_DIR/lib/core.sh"
source "$SCRIPT_DIR/lib/detect.sh"
source "$SCRIPT_DIR/lib/roles.sh"
source "$SCRIPT_DIR/lib/packages.sh"
# Initialize core system
init_core
# Ensure sudo access
sudo -v
# Detect system and hardware
detect_system
detect_hardware
# Show fancy distro-specific header
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
show_arch_header "${SYSTEM_INFO[HOSTNAME]}"
;;
"ubuntu"|"debian")
show_ubuntu_header "${SYSTEM_INFO[HOSTNAME]}"
;;
*)
show_header "${SYSTEM_INFO[HOSTNAME]}" "${SYSTEM_INFO[PRETTY_NAME]}"
;;
esac
# Load and configure roles
load_roles
# Show system configuration
show_roles
# Run system health check
system_health_check
# Interactive confirmation
if [ "$INTERACTIVE" == "true" ]; then
if ! confirm "Proceed with system update?"; then
log INFO "Update cancelled by user"
exit 0
fi
interactive_role_selection
fi
echo -e "${GREEN}${CHECK} Starting update process...${RESET}\n"
# Initialize package managers
init_package_managers
setup_package_managers
# Create backup if timeshift is available
if package_installed timeshift; then
section_start=$(date +%s)
log SECTION "Creating system snapshot"
if confirm "Create Timeshift snapshot before update?"; then
(
sudo timeshift --create --comments "Universal update script $(date '+%Y-%m-%d %H:%M:%S')" 2>&1 | tee -a "$LOG_FILE"
) &
spinner $! "Creating system snapshot..."
wait
log SUCCESS "System snapshot created $(show_timer $section_start)"
else
log WARNING "System snapshot skipped"
fi
else
log WARNING "Timeshift not installed - no system snapshot created"
fi
# Update package databases and perform system upgrade
update_package_databases
system_upgrade
# Update AUR packages (Arch only)
if [ "$PACKAGE_MANAGER" == "pacman" ]; then
update_aur_packages
fi
# Update Flatpak and Snap packages
update_flatpak_apps
[ "$PACKAGE_MANAGER" == "apt" ] && update_snap_packages
# Install basic system packages
log SECTION "Installing essential system packages"
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
install_packages base-devel linux-headers git bc cmake gawk wget gettext unzip curl inetutils python python-pip python-pipx rustup
;;
"ubuntu"|"debian")
install_packages build-essential git gawk imagemagick gpg ninja-build gettext cmake unzip curl libssl-dev libffi-dev file libudev-dev pkg-config locales btop ncdu ranger timeshift
;;
esac
# Create symbolic links for configuration files
log SECTION "Setting up configuration links"
mkdir -p ~/.local/bin ~/.config
# Link bash configuration
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
ln -sf ~/linuxbox/bashrc_arch ~/.bashrc
;;
"ubuntu"|"debian")
if [ "${SYSTEM_INFO[WSL]}" == "yes" ]; then
ln -sf ~/linuxbox/bashrc_ubuntu ~/.bashrc
ln -sf ~/linuxbox/gitconfig.work ~/.gitconfig
else
ln -sf ~/linuxbox/bashrc_ubuntu ~/.bashrc
ln -sf ~/linuxbox/gitconfig ~/.gitconfig
fi
;;
esac
# Link common configuration files
ln -sf ~/linuxbox/update_wrapper.sh ~/.local/bin/update
# Set locale
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
sudo localectl set-locale LANG=en_US.UTF-8
;;
"ubuntu"|"debian")
sudo locale-gen "en_US.UTF-8" || true
sudo update-locale LANG=en_US.UTF-8 || true
;;
esac
# Load and run distro-specific installation
case "${SYSTEM_INFO[DISTRO]}" in
"arch")
source "$SCRIPT_DIR/arch/arch.sh"
arch_install_all
;;
"ubuntu"|"debian")
source "$SCRIPT_DIR/ubuntu/ubuntu.sh"
ubuntu_install_all
;;
*)
log ERROR "Unsupported distribution: ${SYSTEM_INFO[DISTRO]}"
exit 1
;;
esac
# Final summary and reboot prompt
show_final_summary