Add login display module
This commit is contained in:
parent
b6121b1252
commit
5786ff6cee
2 changed files with 155 additions and 7 deletions
|
|
@ -11,7 +11,7 @@
|
||||||
../../../modules/borg-client.nix
|
../../../modules/borg-client.nix
|
||||||
../../../modules/webdav.nix
|
../../../modules/webdav.nix
|
||||||
../../../modules/container-updater.nix
|
../../../modules/container-updater.nix
|
||||||
../../../modules/smart-report.nix
|
../../../modules/login-display.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# GRUB bootloader with ZFS support
|
# GRUB bootloader with ZFS support
|
||||||
|
|
@ -219,19 +219,19 @@
|
||||||
hideDotFiles = true;
|
hideDotFiles = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# SMART disk health reporting
|
# Login display with SMART disk health status
|
||||||
services.smart-report = {
|
services.login-display = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableSystemdService = true;
|
showSystemInfo = true;
|
||||||
schedule = "08:00:00";
|
showSmartStatus = true;
|
||||||
gotifyToken = "Ac9qKFH5cA.7Yly";
|
smartDrives = {
|
||||||
drives = {
|
|
||||||
"/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431J4R" = "ZFS_Mirror_1";
|
"/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-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_5PK2N4GB" = "Data_Drive_1_12TB";
|
||||||
"/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PJ7Z3LE" = "Data_Drive_2_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-ST16000NM000J-2TW103_WRS0F8BE" = "Parity_Drive_16TB";
|
||||||
};
|
};
|
||||||
|
showDiskUsage = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Borg backup configuration
|
# Borg backup configuration
|
||||||
|
|
|
||||||
148
modules/login-display.nix
Normal file
148
modules/login-display.nix
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.login-display;
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.services.login-display = {
|
||||||
|
enable = mkEnableOption "login information display on SSH sessions";
|
||||||
|
|
||||||
|
showSmartStatus = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Show SMART disk health status";
|
||||||
|
};
|
||||||
|
|
||||||
|
smartDrives = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = {};
|
||||||
|
description = "Drives to monitor for SMART status (device path -> name mapping)";
|
||||||
|
example = {
|
||||||
|
"/dev/disk/by-id/ata-Samsung_SSD" = "System_SSD";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
showSystemInfo = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Show basic system information (hostname, uptime, load)";
|
||||||
|
};
|
||||||
|
|
||||||
|
showDiskUsage = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Show disk usage information";
|
||||||
|
};
|
||||||
|
|
||||||
|
diskUsagePaths = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ "/" ];
|
||||||
|
description = "Paths to check for disk usage";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# Add smartmontools if SMART status is enabled
|
||||||
|
environment.systemPackages = mkIf cfg.showSmartStatus [ pkgs.smartmontools ];
|
||||||
|
|
||||||
|
# Configure shell login initialization
|
||||||
|
programs.zsh.loginShellInit = mkIf config.programs.zsh.enable (
|
||||||
|
let
|
||||||
|
# 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
|
||||||
|
# Determine if NVMe
|
||||||
|
SMART_OPTS=""
|
||||||
|
if [[ "${device}" == *"nvme"* ]]; then
|
||||||
|
SMART_OPTS="-d nvme"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get health status (using sudo for disk access)
|
||||||
|
HEALTH=$(sudo ${pkgs.smartmontools}/bin/smartctl $SMART_OPTS -H "${device}" 2>/dev/null | ${pkgs.gnugrep}/bin/grep -o "PASSED\|FAILED" | head -1 || echo "UNKNOWN")
|
||||||
|
|
||||||
|
# Get temperature
|
||||||
|
TEMP="N/A"
|
||||||
|
if [[ "$HEALTH" == "PASSED" ]]; then
|
||||||
|
SMART_DATA=$(sudo ${pkgs.smartmontools}/bin/smartctl $SMART_OPTS -A "${device}" 2>/dev/null)
|
||||||
|
if [[ "${device}" == *"nvme"* ]]; then
|
||||||
|
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
|
||||||
|
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
|
||||||
|
else
|
||||||
|
echo " ⚠ ${name}: Device not found"
|
||||||
|
fi
|
||||||
|
'') cfg.smartDrives)}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
# 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
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Build disk usage display
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
|
||||||
|
in ''
|
||||||
|
${systemInfoCode}
|
||||||
|
${smartStatusCode}
|
||||||
|
${diskUsageCode}
|
||||||
|
|
||||||
|
# Add blank line after all info
|
||||||
|
if [[ -n "$SSH_CONNECTION" ]] || [[ -n "$SSH_TTY" ]]; then
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
# Also support bash if needed
|
||||||
|
programs.bash.loginShellInit = mkIf (!config.programs.zsh.enable) (
|
||||||
|
# Same content as zsh
|
||||||
|
programs.zsh.loginShellInit
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue