#!/bin/bash get_device_info() { local pci_addr=$1 local info=$(lspci -s "$pci_addr") echo "$info" } get_drive_details() { local device=$1 local size=$(lsblk -d -o NAME,SIZE | grep "$device" | awk '{print $2}') echo "$size" } get_drive_smart_info() { local device=$1 local smart_info=$(sudo smartctl -A -i -H /dev/$device 2>/dev/null) local temp=$(echo "$smart_info" | grep "Temperature" | awk '{print $10}' | head -1) local type=$(echo "$smart_info" | grep "Rotation Rate" | grep -q "Solid State" && echo "SSD" || echo "HDD") local health=$(echo "$smart_info" | grep "SMART overall-health" | grep -q "PASSED" && echo "✓" || echo "✗") local model=$(echo "$smart_info" | grep "Device Model" | cut -d: -f2 | xargs) echo "$type|$temp°C|$health|$model" } get_drives_info() { local path="/dev/disk/by-path" for drive in "$path"/*; do if [ -L "$drive" ]; then echo "$(basename "$drive") $(readlink -f "$drive")" fi done } # Get physical slot mapping from system get_physical_mapping() { # Map NVMe drives local nvme_info=$(ls -l /dev/disk/by-path/pci-0000:0d:00.0* 2>/dev/null) # Map SATA hot-swap bays using sg_ses or other tools local hotswap_info=$(ls -l /dev/disk/by-path/pci-0000:0c:00.0-ata-* 2>/dev/null) # Map USB devices local usb_info=$(ls -l /dev/disk/by-path/pci-0000:0b:00.0-usb* 2>/dev/null) # Use smartctl to get drive details for drive in $(echo "$hotswap_info" | awk -F'/' '{print $NF}'); do local smart_info=$(get_drive_smart_info "$drive") local size=$(get_drive_details "$drive") # Map drive details to physical location done } declare -A DRIVE_MAPPINGS=( ["medium2"]=" pci-0000:0c:00.0-ata-1:1 pci-0000:0c:00.0-ata-2:2 pci-0000:0c:00.0-ata-3:3 pci-0000:0c:00.0-ata-4:4 pci-0000:0d:00.0-nvme-1:11 " ["large1"]="" ["medium1"]="" ) build_drive_map() { local host=$(hostname) local drive_map=() # Get mapping for current host local mapping=${DRIVE_MAPPINGS[$host]} if [[ -n "$mapping" ]]; then while read -r path_slot; do [[ -z "$path_slot" ]] && continue local path=${path_slot%:*} local slot=${path_slot#*:} if [[ -L "/dev/disk/by-path/$path" ]]; then local drive=$(readlink -f "/dev/disk/by-path/$path" | sed 's/.*\///') drive_map+=("${slot}:${drive}") fi done <<< "$mapping" fi } # Define the ASCII art maps large1=''' ┌─────────────────────────────────────────────────────────────┐ │ large1 │ │ │ │ ┌──────────────────────────────────────────────┐ │ │ │ Motherboard │ │ │ │ │ │ │ │ ┌──┐┌──┐ │ │ │ │ │M1││M2│ │ │ │ │ └──┘└──┘ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ │ │ │ │ 1 │ │ 2 │ │ 3 │ │ │ │ │ │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ │ │ │ │ 4 │ │ 5 │ │ 6 │ │ │ │ │ │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ │ │ │ │ │ │ 7 │ │ 8 │ │ 9 │ │ │ │ │ │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ''' medium1=''' ┌─────────────────────────────────────────────────────────────┐ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ 5 │ │ 6 │ │ 7 │ │ 8 │ │ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │ │ │ │ │ │ │ │ ┌─────────┐ │ │ medium1 │ 9 │ │ │ └─────────┘ │ │ ┌─────────┐ │ │ │ 10 │ │ │ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ''' generate_medium2_layout() { # USB Section printf " External USB [0b:00.0]\n" printf " ┌────────┐ ┌────────┐\n" usb_drives=$(ls -l /dev/disk/by-path/pci-0000:0b:00.0-usb* 2>/dev/null | awk -F'/' '{print $NF}') if [ -n "$usb_drives" ]; then read -r drive1 drive2 <<< $(echo "$usb_drives") printf " │ %-6s │ │ %-6s │\n" "${drive1:-EMPTY}" "${drive2:-EMPTY}" fi printf " └────────┘ └────────┘\n\n" # Main chassis printf "┌──────────────────────────────────────────────────────────────┐\n" printf "│ B650D4U3-2Q/BCM │\n" printf "│ │\n" printf "│ NVMe [0d:00.0] Bay 11 │\n" printf "│ ┌────────┐ │\n" printf "│ │ %-6s │ │\n" "${drive_map[11]:-nvme0n1}" printf "│ └────────┘ │\n" printf "│ │\n" printf "│ Front Hot-swap Bays [0c:00.0] │\n" printf "│ ┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐ │\n" # Show slot numbers and drives for bay in {1..10}; do local drive="EMPTY" for mapping in "${drive_map[@]}"; do if [[ $mapping == "$bay:"* ]]; then drive="${mapping#*:}" break fi done printf "│ │%-2d:%-4s │" "$bay" "$drive" done printf " │\n" printf "│ └────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘ │\n" printf "└──────────────────────────────────────────────────────────────┘\n" } microGeneric=''' ┌─┐ ┌─┐ ┌└─┘──└─┘┐ │ 1 2 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └────────┘ ''' # Get the hostname HOSTNAME=$(hostname) # ASCII art based on hostname case "$HOSTNAME" in "large1") echo -e "$large1" ;; "medium1") echo -e "$medium1" ;; "medium2") generate_medium2_layout ;; "micro1" | "micro2") echo -e "$microGeneric" ;; *) echo -e "No ASCII map defined for this hostname." ;; esac map_drives_to_layout() { local server_type=$1 case $server_type in "large1") for i in {1..9}; do local drive_info=$(get_drive_info_for_position $i) echo "Position $i: $drive_info" done ;; esac } #get_drive_details() { # local position=$1 # # Get drive info from lsblk and nvme list # local drive_info=$(lsblk -d -o NAME,SIZE,TYPE | grep "disk") # local nvme_info=$(sudo nvme list 2>/dev/null) # # # Map position to drive using DRIVE_PATHS # local drive_path=$(echo "$DRIVE_PATHS" | grep "position$position" || echo "") # # if [ -z "$drive_path" ]; then # echo "[EMPTY]" # return # fi # # local device_name=$(basename $(readlink -f "$drive_path")) # local size=$(echo "$drive_info" | grep "$device_name" | awk '{print $2}') # # echo "$device_name $size" #} # Enhanced Drive Information Function update_ascii_layout() { local layout="$1" for i in {1..9}; do local drive_details=$(get_drive_details $i) if [[ "$drive_details" == "[EMPTY]" ]]; then layout=${layout//│ $i │/│ [EMPTY] │} else layout=${layout//│ $i │/│ $drive_details │} fi done # Update NVMe slots in motherboard local nvme1=$(get_drive_details "nvme0") local nvme2=$(get_drive_details "nvme1") layout=${layout//│M1│/│${nvme1:0:3}│} layout=${layout//│M2│/│${nvme2:0:3}│} echo "$layout" } DRIVE_PATHS=$(get_drives_info | awk '{print $1, $2}') # Initialize array for "not found" messages not_found=() # Show NVMe Drives only if present nvme_drives=$(sudo nvme list | grep "^/dev") if [ -n "$nvme_drives" ]; then echo -e "\n=== NVMe Drives ===\n" printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MODEL" echo "------------------------------------------------------------" echo "$nvme_drives" | awk '{printf "%-15s %-10s %-10s %-20s\n", $1, $6, "NVMe", $3}' else not_found+=("NVMe drives") fi # Show MMC Drives only if present mmc_output=$(lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep "mmcblk" | sort) if [ -n "$mmc_output" ]; then echo -e "\n=== MMC Drives ===\n" printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT" echo "------------------------------------------------------------" echo "$mmc_output" fi # Show SATA Drives only if present sata_output=$(lsblk -d -o NAME,SIZE,TYPE,MOUNTPOINT | grep "disk" | grep -v "nvme" | grep -v "rbd" | sort | column -t)s if [ -n "$sata_output" ]; then echo -e "\n=== SATA Drives ===\n" printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT" echo "------------------------------------------------------------" echo "$sata_output" fi # Show Ceph RBD Devices only if present rbd_output=$(lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep "rbd" | sort -V) if [ -n "$rbd_output" ]; then echo -e "\n=== Ceph RBD Devices ===\n" printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT" echo "------------------------------------------------------------" echo "$rbd_output" else not_found+=("RBD devices") fi # Check RAID if ! [ -f /proc/mdstat ] || ! grep -q "active" /proc/mdstat; then not_found+=("Software RAID") fi # Check ZFS if ! command -v zpool >/dev/null 2>&1 || [ -z "$(sudo zpool status 2>/dev/null)" ]; then not_found+=("ZFS pools") fi # Display consolidated "not found" messages at the end if [ ${#not_found[@]} -gt 0 ]; then echo -e "\n=== Not Found ===\n" printf "%s\n" "${not_found[@]}" fi