Files
omnixy/install.sh
theArctesian f8ff01f966 documentation
2025-09-26 09:09:19 -07:00

669 lines
22 KiB
Bash
Executable File

#!/usr/bin/env bash
# OmniXY NixOS Installation Script
# Stylized installer with Tokyo Night theme integration
set -e
# Get terminal dimensions for centering
TERM_WIDTH=$(tput cols 2>/dev/null || echo 80)
TERM_HEIGHT=$(tput lines 2>/dev/null || echo 24)
# Tokyo Night Color Palette (using printf for better compatibility)
setup_colors() {
BG=$(printf '\033[48;2;26;27;38m') # #1a1b26
FG=$(printf '\033[38;2;192;202;245m') # #c0caf5
BLUE=$(printf '\033[38;2;122;162;247m') # #7aa2f7
CYAN=$(printf '\033[38;2;125;207;255m') # #7dcfff
GREEN=$(printf '\033[38;2;158;206;106m') # #9ece6a
YELLOW=$(printf '\033[38;2;224;175;104m') # #e0af68
RED=$(printf '\033[38;2;247;118;142m') # #f7768e
PURPLE=$(printf '\033[38;2;187;154;247m') # #bb9af7
ORANGE=$(printf '\033[38;2;255;158;100m') # #ff9e64
DARK_BLUE=$(printf '\033[38;2;65;72;104m') # #414868
# Special effects
BOLD=$(printf '\033[1m')
DIM=$(printf '\033[2m')
UNDERLINE=$(printf '\033[4m')
BLINK=$(printf '\033[5m')
RESET=$(printf '\033[0m')
CLEAR=$(printf '\033[2J')
CURSOR_HOME=$(printf '\033[H')
}
# Initialize colors
setup_colors
# Utility functions
center_text() {
local text="$1"
local width=${2:-$TERM_WIDTH}
# Strip ANSI codes for accurate length calculation
local clean_text=$(echo "$text" | sed 's/\x1b\[[0-9;]*m//g')
local padding=$(( (width - ${#clean_text}) / 2 ))
if [ $padding -gt 0 ]; then
printf "%*s%b\n" $padding "" "$text"
else
printf "%b\n" "$text"
fi
}
progress_bar() {
local progress=$1
local width=50
local filled=$((progress * width / 100))
local empty=$((width - filled))
printf "\r${BLUE}["
printf "%*s" $filled | tr ' ' '█'
printf "%*s" $empty | tr ' ' '░'
printf "] ${CYAN}%d%%${RESET}" $progress
}
animate_text() {
local text="$1"
local color="$2"
local delay=${3:-0.03}
for ((i=0; i<${#text}; i++)); do
printf "${color}%c" "${text:$i:1}"
sleep $delay
done
printf "${RESET}"
}
loading_spinner() {
local pid=$1
local message="$2"
local spinner='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
local i=0
while kill -0 $pid 2>/dev/null; do
printf "\r${CYAN}%c ${FG}%s${RESET}" "${spinner:$i:1}" "$message"
i=$(( (i+1) % ${#spinner} ))
sleep 0.1
done
printf "\r${GREEN}${FG}%s${RESET}\n" "$message"
}
# Set terminal background and clear
setup_terminal() {
printf "${CLEAR}${CURSOR_HOME}"
# Don't set background color as it may not work in all terminals
}
# Stylized banner with proper escaping
show_banner() {
clear
setup_terminal
# Add some vertical spacing
for ((i=0; i<3; i++)); do echo; done
# Main logo - using simpler ASCII that works better
echo
center_text "${CYAN}${BOLD} ██████╗ ███╗ ███╗███╗ ██╗██╗██╗ ██╗██╗ ██╗"
center_text "██╔═══██╗████╗ ████║████╗ ██║██║╚██╗██╔╝╚██╗ ██╔╝"
center_text "${BLUE}██║ ██║██╔████╔██║██╔██╗ ██║██║ ╚███╔╝ ╚████╔╝ "
center_text "██║ ██║██║╚██╔╝██║██║╚██╗██║██║ ██╔██╗ ╚██╔╝ "
center_text "${PURPLE}╚██████╔╝██║ ╚═╝ ██║██║ ╚████║██║██╔╝ ██╗ ██║ "
center_text " ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝ ╚═╝ ${RESET}"
echo
# Subtitle with typewriter effect
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
animate_text "Welcome to the linux world" "$CYAN" 0.05
echo
echo
# Version and edition info
center_text "${DIM}${FG}NixOS Edition • Version 0.1 • Tokyo Night Theme${RESET}"
echo
# Decorative border
printf "%*s" $(( (TERM_WIDTH - 60) / 2 )) ""
printf "${DARK_BLUE}"
for ((i=0; i<60; i++)); do printf "═"; done
printf "${RESET}\n"
echo
}
# Stylized section headers
section_header() {
local title="$1"
local icon="$2"
local width=60
echo
printf "%*s" $(( (TERM_WIDTH - width) / 2 )) ""
printf "${BLUE}"
for ((i=0; i<width-2; i++)); do printf "─"; done
printf "${RESET}\n"
local header_text=" $icon $title"
local header_padding=$((width - 4 - ${#header_text}))
printf "%*s" $(( (TERM_WIDTH - width) / 2 )) ""
printf "${BLUE}${BOLD}${CYAN}%s%*s${BLUE}${RESET}\n" "$header_text" $header_padding ""
printf "%*s" $(( (TERM_WIDTH - width) / 2 )) ""
printf "${BLUE}"
for ((i=0; i<width-2; i++)); do printf "─"; done
printf "${RESET}\n"
echo
}
# Clear screen and show minimal context for user input
prepare_input_screen() {
local title="$1"
local subtitle="$2"
clear
setup_terminal
# Minimal header
echo
center_text "${CYAN}${BOLD}$title${RESET}"
if [[ -n "$subtitle" ]]; then
center_text "${DIM}${FG}$subtitle${RESET}"
fi
echo
}
# Enhanced user input with validation
get_input() {
local prompt="$1"
local default="$2"
local validator="$3"
while true; do
# Add some spacing before prompt
echo
center_text "${FG}$prompt${RESET}"
if [[ -n "$default" ]]; then
center_text "${DIM}(default: $default)${RESET}"
fi
printf "%*s${CYAN}${RESET}" $(( TERM_WIDTH / 2 - 2 )) ""
read -r input
input=${input:-$default}
if [[ -z "$validator" ]] || (eval "test_input='$input'; $validator"); then
echo "$input"
return
else
center_text "${RED}❌ Invalid input. Please try again.${RESET}"
fi
done
}
# Check functions with styled output
check_nixos() {
section_header "System Verification" "🔍"
printf "%*s${FG}Checking NixOS installation..." $(( (TERM_WIDTH - 35) / 2 )) ""
sleep 1
if [ ! -f /etc/NIXOS ]; then
printf "\r%*s${RED}❌ Not running on NixOS${RESET}\n" $(( (TERM_WIDTH - 25) / 2 )) ""
echo
center_text "${RED}${BOLD}ERROR: This installer requires NixOS${RESET}"
center_text "${FG}Please install NixOS first: ${UNDERLINE}https://nixos.org/download.html${RESET}"
echo
exit 1
else
printf "\r%*s${GREEN}✅ NixOS detected${RESET}\n" $(( (TERM_WIDTH - 20) / 2 )) ""
fi
printf "%*s${FG}Checking permissions..." $(( (TERM_WIDTH - 25) / 2 )) ""
sleep 0.5
if [ "$EUID" -eq 0 ]; then
printf "\r%*s${YELLOW}⚠️ Running as root${RESET}\n" $(( (TERM_WIDTH - 20) / 2 )) ""
echo
center_text "${YELLOW}Warning: Running as root is not recommended${RESET}"
center_text "${FG}It's safer to run as a regular user with sudo access${RESET}"
echo
echo
center_text "${CYAN}Continue anyway?${RESET}"
printf "%*s${CYAN}(y/N): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
echo
if [[ ! $reply =~ ^[Yy]$ ]]; then
center_text "${FG}Installation cancelled${RESET}"
exit 1
fi
else
printf "\r%*s${GREEN}✅ User permissions OK${RESET}\n" $(( (TERM_WIDTH - 25) / 2 )) ""
fi
}
# Enhanced backup with progress
backup_config() {
if [ -d /etc/nixos ]; then
section_header "Configuration Backup" "💾"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/etc/nixos.backup.$TIMESTAMP"
center_text "${FG}Creating configuration backup${RESET}"
center_text "${DIM}${CYAN}$BACKUP_DIR${RESET}"
echo
# Simulate progress for visual appeal
for i in {1..20}; do
progress_bar $((i * 5))
sleep 0.05
done
echo
sudo cp -r /etc/nixos "$BACKUP_DIR" &
loading_spinner $! "Backing up existing configuration"
fi
}
# Installation with progress tracking
install_config() {
section_header "Installing Configuration" "📦"
center_text "${FG}Installing OmniXY configuration files...${RESET}"
echo
# Create directory
(sudo mkdir -p /etc/nixos && sleep 0.5) &
loading_spinner $! "Creating configuration directory"
# Copy files with progress simulation
(sudo cp -r ./* /etc/nixos/ && sleep 1) &
loading_spinner $! "Copying configuration files"
# Set permissions
(sudo chown -R root:root /etc/nixos && sudo chmod 755 /etc/nixos && sleep 0.5) &
loading_spinner $! "Setting file permissions"
}
# Enhanced user configuration
update_user() {
prepare_input_screen "OmniXY User Configuration" "Set up your user account"
local username
username=$(get_input "Enter your username" "user" '[[ "$test_input" =~ ^[a-zA-Z][a-zA-Z0-9_-]*$ ]]')
echo
center_text "${FG}Configuring system for user: ${CYAN}${BOLD}$username${RESET}"
echo
# Update configuration files
(sudo sed -i "s/user = \"user\"/user = \"$username\"/" /etc/nixos/configuration.nix && sleep 0.3) &
loading_spinner $! "Updating main configuration"
(sudo sed -i "s/home.username = \"user\"/home.username = \"$username\"/" /etc/nixos/home.nix 2>/dev/null && sleep 0.3) &
loading_spinner $! "Updating home configuration"
(sudo sed -i "s|home.homeDirectory = \"/home/user\"|home.homeDirectory = \"/home/$username\"|" /etc/nixos/home.nix 2>/dev/null && sleep 0.3) &
loading_spinner $! "Setting home directory"
}
# Stylized theme selection
select_theme() {
prepare_input_screen "OmniXY Theme Selection" "Choose your visual style"
local themes=(
"Tokyo Night - Dark theme with vibrant colors"
"Catppuccin - Pastel theme with modern aesthetics"
"Gruvbox - Retro theme with warm colors"
"Nord - Arctic theme with cool colors"
"Everforest - Green forest theme"
"Rose Pine - Cozy theme with muted colors"
"Kanagawa - Japanese-inspired theme"
"Catppuccin Latte - Light variant"
"Matte Black - Minimalist dark theme"
"Osaka Jade - Jade green theme"
"Ristretto - Coffee-inspired theme"
)
center_text "${BOLD}${PURPLE}Available Themes:${RESET}"
echo
# Display themes in organized layout
for i in "${!themes[@]}"; do
local num=$((i + 1))
if [ $num -le 9 ]; then
center_text "${BOLD}${CYAN} $num.${RESET} ${FG}${themes[$i]}"
else
center_text "${BOLD}${CYAN}$num.${RESET} ${FG}${themes[$i]}"
fi
done
echo
echo
# Clear instruction section
center_text "${BOLD}${YELLOW}Instructions:${RESET}"
center_text "${FG}Enter the number of your preferred theme${RESET}"
center_text "${DIM}Press Enter to use the default (Tokyo Night)${RESET}"
echo
# Create visible input box
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}╭──────────────────────────────────────╮${RESET}\n"
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}${RESET}"
printf "%*s${FG}Theme Selection${RESET}%*s" 12 "" 12 ""
printf "${BLUE}${RESET}\n"
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}├──────────────────────────────────────┤${RESET}\n"
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}${RESET}%*s${CYAN}Enter choice (1-11):${RESET}%*s" 7 "" 7 ""
printf "${BLUE}${RESET}\n"
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}${RESET}%*s${DIM}Default: 1${RESET}%*s" 13 "" 13 ""
printf "${BLUE}${RESET}\n"
printf "%*s" $(( (TERM_WIDTH - 40) / 2 )) ""
printf "${BLUE}╰──────────────────────────────────────╯${RESET}\n"
printf "%*s${CYAN}${RESET}" $(( TERM_WIDTH / 2 - 2 )) ""
# Get input with validation
local theme_choice
while true; do
read -r theme_choice
theme_choice=${theme_choice:-1}
if [[ "$theme_choice" =~ ^([1-9]|1[01])$ ]]; then
break
else
printf "%*s${RED}❌ Please enter a number between 1 and 11${RESET}\n" $(( (TERM_WIDTH - 45) / 2 )) ""
printf "%*s${CYAN}${RESET}" $(( TERM_WIDTH / 2 - 2 )) ""
fi
done
local theme_names=("tokyo-night" "catppuccin" "gruvbox" "nord" "everforest" "rose-pine" "kanagawa" "catppuccin-latte" "matte-black" "osaka-jade" "ristretto")
local selected_theme=${theme_names[$((theme_choice - 1))]}
echo
center_text "${GREEN}✅ Selected theme: ${CYAN}${BOLD}$selected_theme${RESET}"
echo
(sudo sed -i "s/currentTheme = \".*\"/currentTheme = \"$selected_theme\"/" /etc/nixos/configuration.nix && sleep 0.5) &
loading_spinner $! "Applying theme configuration"
}
# Feature configuration
configure_features() {
section_header "Feature Configuration" "⚙️ "
center_text "${FG}Configure optional features:${RESET}"
echo
# Security features
center_text "${BOLD}${PURPLE}Security Features:${RESET}"
echo
center_text "${FG}Enable fingerprint authentication?${RESET}"
printf "%*s${CYAN}(y/N): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
if [[ $reply =~ ^[Yy]$ ]]; then
center_text "${GREEN}✅ Fingerprint authentication enabled${RESET}"
local config_dir="/etc/nixos"
if [ "$INSTALL_MODE" = "fresh" ]; then
config_dir="/mnt/etc/nixos"
fi
sudo sed -i 's/fingerprint = {/fingerprint = {\n enable = true;/' "$config_dir/configuration.nix"
fi
echo
center_text "${FG}Enable FIDO2 security keys?${RESET}"
printf "%*s${CYAN}(y/N): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
if [[ $reply =~ ^[Yy]$ ]]; then
center_text "${GREEN}✅ FIDO2 authentication enabled${RESET}"
local config_dir="/etc/nixos"
if [ "$INSTALL_MODE" = "fresh" ]; then
config_dir="/mnt/etc/nixos"
fi
sudo sed -i 's/fido2 = {/fido2 = {\n enable = true;/' "$config_dir/configuration.nix"
fi
echo
center_text "${BOLD}${BLUE}Development Features:${RESET}"
echo
center_text "${FG}Enable Docker support?${RESET}"
printf "%*s${CYAN}(y/N): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
if [[ $reply =~ ^[Yy]$ ]]; then
center_text "${GREEN}✅ Docker support enabled${RESET}"
# Add Docker configuration
fi
echo
center_text "${BOLD}${YELLOW}Gaming Features:${RESET}"
echo
center_text "${FG}Enable gaming support (Steam, Wine)?${RESET}"
printf "%*s${CYAN}(y/N): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
if [[ $reply =~ ^[Yy]$ ]]; then
center_text "${GREEN}✅ Gaming support enabled${RESET}"
# Add gaming configuration
fi
}
# Hardware configuration generation
generate_hardware_config() {
section_header "Hardware Configuration" "🔧"
if [ ! -f /etc/nixos/hardware-configuration.nix ]; then
center_text "${FG}Generating hardware-specific configuration...${RESET}"
echo
(sudo nixos-generate-config --root / && sleep 1) &
loading_spinner $! "Scanning hardware configuration"
else
center_text "${YELLOW}⚠️ Hardware configuration already exists${RESET}"
center_text "${DIM}${FG}Skipping hardware generation...${RESET}"
sleep 1
fi
}
# System building with enhanced progress
build_system() {
section_header "System Build" "🏗️ "
center_text "${YELLOW}${BOLD}⚠️ IMPORTANT NOTICE ⚠️${RESET}"
center_text "${FG}This process may take 10-45 minutes depending on your system${RESET}"
center_text "${FG}A stable internet connection is required${RESET}"
echo
echo
center_text "${CYAN}${BOLD}Continue with system build?${RESET}"
printf "%*s${CYAN}(Y/n): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
echo
if [[ $reply =~ ^[Nn]$ ]]; then
center_text "${YELLOW}Build postponed. Run this command later:${RESET}"
center_text "${CYAN}sudo nixos-rebuild switch --flake /etc/nixos#omnixy${RESET}"
return
fi
echo
center_text "${FG}Building NixOS system configuration...${RESET}"
center_text "${DIM}${FG}This includes downloading packages and compiling the system${RESET}"
echo
# Start build in background and show spinner
sudo nixos-rebuild switch --flake /etc/nixos#omnixy &
local build_pid=$!
# Enhanced progress indication
local dots=""
local build_messages=(
"Downloading Nix packages..."
"Building system dependencies..."
"Compiling configuration..."
"Setting up services..."
"Finalizing installation..."
)
local msg_index=0
local counter=0
while kill -0 $build_pid 2>/dev/null; do
if (( counter % 30 == 0 && msg_index < ${#build_messages[@]} )); then
echo
center_text "${CYAN}${build_messages[$msg_index]}${RESET}"
((msg_index++))
fi
printf "\r%*s${CYAN}Building system" $(( (TERM_WIDTH - 20) / 2 )) ""
dots+="."
if [ ${#dots} -gt 6 ]; then dots=""; fi
printf "%s${RESET}" "$dots"
sleep 1
((counter++))
done
wait $build_pid
local exit_code=$?
echo
if [ $exit_code -eq 0 ]; then
center_text "${GREEN}${BOLD}✅ System build completed successfully!${RESET}"
else
center_text "${RED}${BOLD}❌ Build failed with errors${RESET}"
center_text "${FG}Check the output above for details${RESET}"
exit $exit_code
fi
}
# Completion screen
show_complete() {
clear
setup_terminal
# Add spacing
for ((i=0; i<2; i++)); do echo; done
# Success banner
printf "%*s${GREEN}${BOLD}" $(( (TERM_WIDTH - 60) / 2 )) ""
echo "╭──────────────────────────────────────────────────────────╮"
printf "%*s${GREEN}" $(( (TERM_WIDTH - 60) / 2 )) ""
printf "%*s🎉 OmniXY Installation Complete! 🎉%*s│\n" 14 "" 14 ""
printf "%*s${GREEN}╰──────────────────────────────────────────────────────────╯${RESET}\n" $(( (TERM_WIDTH - 60) / 2 )) ""
echo
echo
# Quick start section
section_header "Quick Start Guide" "🚀"
center_text "${CYAN}${BOLD}Essential Commands:${RESET}"
center_text "${FG}${DIM}Run these commands to get started${RESET}"
echo
center_text "${CYAN}omnixy-menu${RESET} ${FG}- Interactive system menu${RESET}"
center_text "${CYAN}omnixy-info${RESET} ${FG}- System information display${RESET}"
center_text "${CYAN}omnixy-theme${RESET} ${FG}- Switch between themes${RESET}"
center_text "${CYAN}omnixy-security${RESET} ${FG}- Configure security features${RESET}"
echo
section_header "Keyboard Shortcuts" "⌨️ "
center_text "${PURPLE}${BOLD}Hyprland Window Manager:${RESET}"
echo
center_text "${CYAN}Super + Return${RESET} ${FG}- Open terminal${RESET}"
center_text "${CYAN}Super + R${RESET} ${FG}- Application launcher${RESET}"
center_text "${CYAN}Super + B${RESET} ${FG}- Web browser${RESET}"
center_text "${CYAN}Super + E${RESET} ${FG}- File manager${RESET}"
center_text "${CYAN}Super + Q${RESET} ${FG}- Close window${RESET}"
echo
section_header "Next Steps" "📋"
center_text "${YELLOW}${BOLD}Recommended Actions:${RESET}"
echo
center_text "${FG}1. ${CYAN}Reboot your system${RESET} ${FG}- Apply all changes${RESET}"
center_text "${FG}2. ${CYAN}Run omnixy-security status${RESET} ${FG}- Check security setup${RESET}"
center_text "${FG}3. ${CYAN}Configure fingerprint/FIDO2${RESET} ${FG}- Enhanced security${RESET}"
center_text "${FG}4. ${CYAN}Explore themes${RESET} ${FG}- Try different color schemes${RESET}"
echo
center_text "${BLUE}${UNDERLINE}https://github.com/TheArctesian/omnixy${RESET} ${FG}- Project homepage${RESET}"
echo
center_text "${DIM}${FG}Thank you for choosing OmniXY! ${CYAN}❤️${RESET}"
echo
# Auto-reboot prompt
echo
center_text "${YELLOW}${BOLD}Reboot now to complete installation?${RESET}"
printf "%*s${CYAN}(Y/n): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
echo
if [[ ! $reply =~ ^[Nn]$ ]]; then
center_text "${GREEN}Rebooting in 3 seconds...${RESET}"
sleep 1
center_text "${GREEN}Rebooting in 2 seconds...${RESET}"
sleep 1
center_text "${GREEN}Rebooting in 1 second...${RESET}"
sleep 1
sudo reboot
else
center_text "${FG}Remember to reboot when convenient!${RESET}"
fi
}
# Main installation orchestrator
main() {
# Trap to restore terminal on exit
trap 'printf "\033[0m\033[?25h"; stty sane 2>/dev/null || true' EXIT
# Hide cursor during installation
printf '\033[?25l'
show_banner
sleep 2
section_header "Welcome to OmniXY" "🌟"
center_text "${FG}Transform your NixOS into a beautiful, modern desktop experience${RESET}"
center_text "${DIM}${FG}This installer will guide you through the complete setup process${RESET}"
echo
echo
center_text "${CYAN}${BOLD}Ready to begin installation?${RESET}"
printf "%*s${CYAN}(Y/n): ${RESET}" $(( (TERM_WIDTH - 10) / 2 )) ""
read -n 1 -r reply
echo
echo
if [[ $reply =~ ^[Nn]$ ]]; then
center_text "${FG}Installation cancelled. Come back anytime!${RESET}"
exit 0
fi
# Installation flow with enhanced UX
check_nixos
backup_config
install_config
generate_hardware_config
update_user
select_theme
configure_features
build_system
show_complete
# Restore cursor
printf '\033[?25h'
}
# Start the installation
main "$@"