diff --git a/hosts/nixos/hs/system.nix b/hosts/nixos/hs/system.nix index d460f27..a4c5872 100644 --- a/hosts/nixos/hs/system.nix +++ b/hosts/nixos/hs/system.nix @@ -224,9 +224,9 @@ smartDrives = { "/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431J4R" = "ZFS_Mirror_1"; "/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431KEG" = "ZFS_Mirror_2"; - "/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PK2N4GB" = "Data_Drive_1_12TB"; - "/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PJ7Z3LE" = "Data_Drive_2_12TB"; - "/dev/disk/by-id/ata-ST16000NM000J-2TW103_WRS0F8BE" = "Parity_Drive_16TB"; + "/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PK2N4GB" = "Data_1_12TB"; + "/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PJ7Z3LE" = "Data_2_12TB"; + "/dev/disk/by-id/ata-ST16000NM000J-2TW103_WRS0F8BE" = "Parity_16TB"; }; showDiskUsage = true; diskUsagePaths = [ "/" "/mnt/storage" "/mnt/parity" ]; diff --git a/modules/login-display.nix b/modules/login-display.nix index 230d3d6..c8df676 100644 --- a/modules/login-display.nix +++ b/modules/login-display.nix @@ -51,96 +51,151 @@ in # Configure shell login initialization programs.zsh.loginShellInit = mkIf config.programs.zsh.enable ( let + # ANSI color codes for truecolor (using \033 for better compatibility) + colors = { + reset = "\\033[0m"; + dim = "\\033[2m"; + cyan = "\\033[38;2;0;200;255m"; + blue = "\\033[38;2;100;150;255m"; + green = "\\033[38;2;80;250;123m"; + yellow = "\\033[38;2;241;250;140m"; + orange = "\\033[38;2;255;184;108m"; + red = "\\033[38;2;255;85;85m"; + gray = "\\033[38;2;100;100;120m"; + }; + # Build SMART status display smartStatusCode = optionalString cfg.showSmartStatus '' - # Only show on SSH sessions - if [[ -n "$SSH_CONNECTION" ]] || [[ -n "$SSH_TTY" ]]; then - echo "" - echo "=== Disk Health Status ===" - - ${concatStringsSep "\n" (mapAttrsToList (device: name: '' - if [[ -e "${device}" ]]; then - # Get health status (using sudo for disk access) - # Use separate commands for NVMe vs SATA to avoid variable expansion issues - if [[ "${device}" == *"nvme"* ]]; then - HEALTH_OUTPUT=$(sudo ${pkgs.smartmontools}/bin/smartctl -d nvme -H "${device}" 2>/dev/null) - else - HEALTH_OUTPUT=$(sudo ${pkgs.smartmontools}/bin/smartctl -H "${device}" 2>/dev/null) - fi - - if HEALTH=$(echo "$HEALTH_OUTPUT" | ${pkgs.gnugrep}/bin/grep -o "PASSED\|FAILED" | head -1); then - : # HEALTH is set - else - HEALTH="UNKNOWN" - fi - - # Get temperature - TEMP="N/A" - if [[ "$HEALTH" == "PASSED" ]]; then - if [[ "${device}" == *"nvme"* ]]; then - SMART_DATA=$(sudo ${pkgs.smartmontools}/bin/smartctl -d nvme -A "${device}" 2>/dev/null) - TEMP=$(echo "$SMART_DATA" | ${pkgs.gawk}/bin/awk '/^Temperature:/ {print $2}' | head -1) - [[ -n "$TEMP" && "$TEMP" =~ ^[0-9]+$ ]] && TEMP="''${TEMP}°C" || TEMP="N/A" - else - SMART_DATA=$(sudo ${pkgs.smartmontools}/bin/smartctl -A "${device}" 2>/dev/null) - TEMP=$(echo "$SMART_DATA" | ${pkgs.gawk}/bin/awk '/Temperature_Celsius/ {print $10}' | head -1) - [[ -n "$TEMP" && "$TEMP" =~ ^[0-9]+$ ]] && TEMP="''${TEMP}°C" || TEMP="N/A" - fi - fi - - # Display status with color - if [[ "$HEALTH" == "PASSED" ]]; then - echo " ✓ ${name}: $HEALTH (Temp: $TEMP)" - else - echo " ✗ ${name}: $HEALTH" - fi + ${concatStringsSep "\n" (mapAttrsToList (device: name: '' + if [[ -e "${device}" ]]; then + # Get health status + if [[ "${device}" == *"nvme"* ]]; then + HEALTH_OUTPUT=$(sudo ${pkgs.smartmontools}/bin/smartctl -d nvme -H "${device}" 2>/dev/null) else - echo " ⚠ ${name}: Device not found" + HEALTH_OUTPUT=$(sudo ${pkgs.smartmontools}/bin/smartctl -H "${device}" 2>/dev/null) fi - '') cfg.smartDrives)} - fi + + if HEALTH=$(echo "$HEALTH_OUTPUT" | ${pkgs.gnugrep}/bin/grep -o "PASSED\|FAILED" | head -1); then + : # HEALTH is set + else + HEALTH="UNKNOWN" + fi + + # Get temperature + TEMP="N/A" + if [[ "$HEALTH" == "PASSED" ]]; then + if [[ "${device}" == *"nvme"* ]]; then + SMART_DATA=$(sudo ${pkgs.smartmontools}/bin/smartctl -d nvme -A "${device}" 2>/dev/null) + TEMP=$(echo "$SMART_DATA" | ${pkgs.gawk}/bin/awk '/^Temperature:/ {print $2}' | head -1) + [[ -n "$TEMP" && "$TEMP" =~ ^[0-9]+$ ]] && TEMP="''${TEMP}" || TEMP="N/A" + else + SMART_DATA=$(sudo ${pkgs.smartmontools}/bin/smartctl -A "${device}" 2>/dev/null) + TEMP=$(echo "$SMART_DATA" | ${pkgs.gawk}/bin/awk '/Temperature_Celsius/ {print $10}' | head -1) + [[ -n "$TEMP" && "$TEMP" =~ ^[0-9]+$ ]] && TEMP="''${TEMP}" || TEMP="N/A" + fi + fi + + # Color-code status and temperature + if [[ "$HEALTH" == "PASSED" ]]; then + STATUS="\\033[38;2;80;250;123m✓\\033[0m" + HEALTH_COLOR="\\033[38;2;80;250;123m" + # Color temp based on value + if [[ "$TEMP" =~ ^[0-9]+$ ]]; then + if [[ $TEMP -ge 70 ]]; then + TEMP_COLOR="\\033[38;2;255;85;85m" + elif [[ $TEMP -ge 50 ]]; then + TEMP_COLOR="\\033[38;2;255;184;108m" + else + TEMP_COLOR="\\033[38;2;241;250;140m" + fi + TEMP_STR="$(printf "%b" "''${TEMP_COLOR}''${TEMP}°C\\033[0m")" + else + TEMP_STR="$(printf "%b" "\\033[2m$TEMP\\033[0m")" + fi + elif [[ "$HEALTH" == "FAILED" ]]; then + STATUS="\\033[38;2;255;85;85m✗\\033[0m" + HEALTH_COLOR="\\033[38;2;255;85;85m" + TEMP_STR="$(printf "%b" "\\033[2m$TEMP\\033[0m")" + else + STATUS="\\033[38;2;241;250;140m⚠\\033[0m" + HEALTH_COLOR="\\033[38;2;241;250;140m" + TEMP_STR="$(printf "%b" "\\033[2m$TEMP\\033[0m")" + fi + + printf " %b \\033[2m%-15s\\033[0m %b%-7s\\033[0m %s\n" "$STATUS" "${name}" "$HEALTH_COLOR" "$HEALTH" "$TEMP_STR" + else + printf " \\033[38;2;241;250;140m⚠\\033[0m \\033[2m%-15s\\033[0m \\033[38;2;255;85;85m%-20s\\033[0m\n" "${name}" "Not found" + fi + '') cfg.smartDrives)} ''; # Build system info display systemInfoCode = optionalString cfg.showSystemInfo '' - # Only show on SSH sessions - if [[ -n "$SSH_CONNECTION" ]] || [[ -n "$SSH_TTY" ]]; then - echo "" - echo "=== System Information ===" - echo " Hostname: $(hostname)" - # Parse uptime output to get readable format - UPTIME_STR=$(uptime | ${pkgs.gawk}/bin/awk '{ - # Extract the uptime part (between "up" and "user" or "load") - match($0, /up\s+(.+?),\s+[0-9]+\s+user/, arr) - if (arr[1] != "") { - print arr[1] - } - }') - echo " Uptime: $UPTIME_STR" - echo " Load: $(uptime | ${pkgs.gawk}/bin/awk -F'load average:' '{print $2}')" - fi + # Parse uptime + UPTIME_STR=$(uptime | ${pkgs.gawk}/bin/awk '{ + match($0, /up\s+(.+?),\s+[0-9]+\s+user/, arr) + if (arr[1] != "") { + gsub(/^ +| +$/, "", arr[1]) + # Shorten format: "5 days, 3:42" -> "5d 3h" + gsub(/ days?,/, "d", arr[1]) + gsub(/ hours?,/, "h", arr[1]) + gsub(/ mins?,/, "m", arr[1]) + gsub(/:[0-9]+$/, "", arr[1]) + print arr[1] + } + }') + LOAD=$(uptime | ${pkgs.gawk}/bin/awk -F'load average:' '{gsub(/^ +| +$/, "", $2); print $2}') + + printf " \\033[38;2;0;200;255m%s\\033[0m \\033[2m·\\033[0m \\033[2m↑\\033[0m %s \\033[2m· load\\033[0m %s\n" "$(hostname)" "$UPTIME_STR" "$LOAD" ''; - # Build disk usage display + # Build disk usage display with bar diskUsageCode = optionalString cfg.showDiskUsage '' - # Only show on SSH sessions - if [[ -n "$SSH_CONNECTION" ]] || [[ -n "$SSH_TTY" ]]; then - echo "" - echo "=== Disk Usage ===" - ${concatMapStringsSep "\n" (path: '' - df -h "${path}" | ${pkgs.gawk}/bin/awk 'NR==2 {printf " ${path}: %s / %s (%s used)\n", $3, $2, $5}' - '') cfg.diskUsagePaths} - fi + ${concatMapStringsSep "\n" (path: '' + DF_OUTPUT=$(df -h "${path}" | ${pkgs.gawk}/bin/awk 'NR==2 {print $3, $2, $5}') + read -r USED TOTAL PCT <<< "$DF_OUTPUT" + PCT_NUM=''${PCT%\%} + + # Create progress bar (10 chars) + FILLED=$((PCT_NUM / 10)) + EMPTY=$((10 - FILLED)) + BAR="" + for ((i=0; i 0); + hasStorage = cfg.showDiskUsage && (builtins.length cfg.diskUsagePaths > 0); + in '' - ${systemInfoCode} - ${smartStatusCode} - ${diskUsageCode} - - # Add blank line after all info if [[ -n "$SSH_CONNECTION" ]] || [[ -n "$SSH_TTY" ]]; then echo "" + printf "\\033[38;2;0;200;255m━━ System ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" + ${systemInfoCode} + ${optionalString hasDisks '' + printf "\\033[38;2;100;150;255m━━ Disks ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" + ${smartStatusCode} + ''} + ${optionalString hasStorage '' + printf "\\033[38;2;100;150;255m━━ Storage ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\033[0m\n" + ${diskUsageCode} + ''} + echo "" fi '' );