2024-12-09 21:59:32 -05:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
2025-03-01 11:58:15 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 13:34:53 -05:00
|
|
|
get_bay_number() {
|
|
|
|
|
local drive=$1
|
|
|
|
|
local path=$(readlink -f "/dev/disk/by-path/"*$(basename "$drive"))
|
|
|
|
|
|
|
|
|
|
# Extract bay number from the path based on medium2's mapping
|
|
|
|
|
for mapping in ${DRIVE_MAPPINGS[medium2]}; do
|
|
|
|
|
if [[ $path =~ $mapping ]]; then
|
|
|
|
|
echo "${mapping##*:}"
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:22:15 -05:00
|
|
|
get_physical_mapping() {
|
2025-03-01 13:22:51 -05:00
|
|
|
local -A drive_map
|
|
|
|
|
|
2025-03-01 12:22:15 -05:00
|
|
|
# Map NVMe drives
|
2025-03-01 13:31:59 -05:00
|
|
|
for nvme in /dev/nvme*n1; do
|
|
|
|
|
if [ -b "$nvme" ]; then
|
|
|
|
|
drive_map[11]=$(basename "$nvme")
|
2025-03-01 13:22:51 -05:00
|
|
|
fi
|
|
|
|
|
done
|
2025-03-01 12:22:15 -05:00
|
|
|
|
2025-03-01 13:31:59 -05:00
|
|
|
# Map SATA drives
|
|
|
|
|
for drive in /dev/sd[a-z]; do
|
|
|
|
|
if [ -b "$drive" ]; then
|
|
|
|
|
local bay=$(get_bay_number "$drive")
|
|
|
|
|
if [[ -n "$bay" ]]; then
|
|
|
|
|
drive_map[$bay]=$(basename "$drive")
|
|
|
|
|
fi
|
|
|
|
|
fi
|
2025-03-01 12:22:15 -05:00
|
|
|
done
|
2025-03-01 13:22:51 -05:00
|
|
|
|
|
|
|
|
echo "$(declare -p drive_map)"
|
2025-03-01 12:22:15 -05:00
|
|
|
}
|
|
|
|
|
|
2025-03-01 13:00:53 -05:00
|
|
|
declare -A DRIVE_MAPPINGS=(
|
|
|
|
|
["medium2"]="
|
2025-03-01 13:11:59 -05:00
|
|
|
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
|
2025-03-01 13:08:32 -05:00
|
|
|
pci-0000:0d:00.0-nvme-1:11
|
2025-03-01 13:00:53 -05:00
|
|
|
"
|
|
|
|
|
)
|
|
|
|
|
|
2025-03-01 13:22:51 -05:00
|
|
|
|
2025-03-01 13:00:53 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-12-09 21:59:32 -05:00
|
|
|
# Define the ASCII art maps
|
|
|
|
|
large1='''
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ large1 │
|
|
|
|
|
│ │
|
2025-02-21 20:41:24 -05:00
|
|
|
│ ┌──────────────────────────────────────────────┐ │
|
|
|
|
|
│ │ Motherboard │ │
|
|
|
|
|
│ │ │ │
|
|
|
|
|
│ │ ┌──┐┌──┐ │ │
|
|
|
|
|
│ │ │M1││M2│ │ │
|
|
|
|
|
│ │ └──┘└──┘ │ │
|
|
|
|
|
│ └──────────────────────────────────────────────┘ │
|
|
|
|
|
│ │
|
2024-12-09 21:59:32 -05:00
|
|
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ │ 1 │ │ 2 │ │ 3 │ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
|
|
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ │ 4 │ │ 5 │ │ 6 │ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
|
|
|
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ │ 7 │ │ 8 │ │ 9 │ │
|
|
|
|
|
│ │ │ │ │ │ │ │
|
|
|
|
|
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
medium1='''
|
|
|
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
|
|
|
│ │
|
|
|
|
|
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
|
|
|
│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │
|
|
|
|
|
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
|
|
|
|
|
│ │
|
|
|
|
|
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
|
|
|
│ │ 5 │ │ 6 │ │ 7 │ │ 8 │ │
|
|
|
|
|
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
|
|
|
|
|
│ │
|
|
|
|
|
│ │
|
|
|
|
|
│ │
|
|
|
|
|
│ ┌─────────┐ │
|
|
|
|
|
│ medium1 │ 9 │ │
|
|
|
|
|
│ └─────────┘ │
|
|
|
|
|
│ ┌─────────┐ │
|
|
|
|
|
│ │ 10 │ │
|
|
|
|
|
│ └─────────┘ │
|
|
|
|
|
│ │
|
|
|
|
|
└─────────────────────────────────────────────────────────────┘
|
|
|
|
|
'''
|
|
|
|
|
|
2025-03-01 11:43:21 -05:00
|
|
|
generate_medium2_layout() {
|
2025-03-01 13:22:51 -05:00
|
|
|
eval "$(get_physical_mapping)"
|
|
|
|
|
|
|
|
|
|
# USB Section with dynamic mapping
|
2025-03-01 12:39:53 -05:00
|
|
|
printf " External USB [0b:00.0]\n"
|
|
|
|
|
printf " ┌────────┐ ┌────────┐\n"
|
2025-03-01 13:22:51 -05:00
|
|
|
printf " │ %-6s │ │ %-6s │\n" "${drive_map[usb1]:-EMPTY}" "${drive_map[usb2]:-EMPTY}"
|
2025-03-01 12:28:18 -05:00
|
|
|
printf " └────────┘ └────────┘\n\n"
|
2025-03-01 13:22:51 -05:00
|
|
|
|
|
|
|
|
# Rest of chassis layout with enhanced drive info
|
2025-03-01 11:58:15 -05:00
|
|
|
printf "┌──────────────────────────────────────────────────────────────┐\n"
|
2025-03-01 12:17:43 -05:00
|
|
|
printf "│ B650D4U3-2Q/BCM │\n"
|
2025-03-01 11:58:15 -05:00
|
|
|
printf "│ │\n"
|
2025-03-01 13:22:51 -05:00
|
|
|
printf "│ NVMe [0d:00.0] Bay 11 │\n"
|
2025-03-01 12:28:18 -05:00
|
|
|
printf "│ ┌────────┐ │\n"
|
2025-03-01 13:22:51 -05:00
|
|
|
printf "│ │ %-6s │ │\n" "${drive_map[11]:-EMPTY}"
|
2025-03-01 12:28:18 -05:00
|
|
|
printf "│ └────────┘ │\n"
|
2025-03-01 11:58:15 -05:00
|
|
|
printf "│ │\n"
|
2025-03-01 12:17:43 -05:00
|
|
|
printf "│ Front Hot-swap Bays [0c:00.0] │\n"
|
2025-03-01 12:28:18 -05:00
|
|
|
printf "│ ┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐┌────────┐ │\n"
|
2025-03-01 13:08:32 -05:00
|
|
|
|
2025-03-01 12:28:18 -05:00
|
|
|
for bay in {1..10}; do
|
2025-03-01 13:22:51 -05:00
|
|
|
printf "│ │%-2d:%-4s │" "$bay" "${drive_map[$bay]:-EMPTY}"
|
2025-03-01 11:43:21 -05:00
|
|
|
done
|
2025-03-01 13:22:51 -05:00
|
|
|
|
2025-03-01 12:28:18 -05:00
|
|
|
printf " │\n"
|
|
|
|
|
printf "│ └────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘└────────┘ │\n"
|
2025-03-01 11:58:15 -05:00
|
|
|
printf "└──────────────────────────────────────────────────────────────┘\n"
|
2025-03-01 11:43:21 -05:00
|
|
|
}
|
2024-12-09 21:59:32 -05:00
|
|
|
|
|
|
|
|
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")
|
2025-03-01 11:43:21 -05:00
|
|
|
generate_medium2_layout
|
2024-12-09 21:59:32 -05:00
|
|
|
;;
|
|
|
|
|
"micro1" | "micro2")
|
|
|
|
|
echo -e "$microGeneric"
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
echo -e "No ASCII map defined for this hostname."
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2025-02-21 20:41:24 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DRIVE_PATHS=$(get_drives_info | awk '{print $1, $2}')
|
|
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# Initialize array for "not found" messages
|
|
|
|
|
not_found=()
|
|
|
|
|
|
2025-03-01 13:22:51 -05:00
|
|
|
|
|
|
|
|
echo -e "\n=== Drive Details with SMART Status ===\n"
|
|
|
|
|
printf "%-15s %-10s %-8s %-8s %-20s %-30s\n" "DEVICE" "SIZE" "TYPE" "TEMP" "HEALTH" "MODEL"
|
|
|
|
|
echo "--------------------------------------------------------------------------------"
|
|
|
|
|
|
|
|
|
|
# For SATA drives
|
|
|
|
|
lsblk -d -o NAME | grep -v "nvme" | grep -v "rbd" | while read device; do
|
|
|
|
|
size=$(get_drive_details "$device")
|
|
|
|
|
smart_info=$(get_drive_smart_info "$device")
|
|
|
|
|
IFS='|' read -r type temp health model <<< "$smart_info"
|
|
|
|
|
printf "%-15s %-10s %-8s %-8s %-20s %-30s\n" "/dev/$device" "$size" "$type" "$temp" "$health" "$model"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# For NVMe drives
|
|
|
|
|
if [ -n "$nvme_drives" ]; then
|
|
|
|
|
while read -r line; do
|
|
|
|
|
device=$(echo "$line" | awk '{print $1}' | sed 's/.*\///')
|
|
|
|
|
size=$(echo "$line" | awk '{print $6}')
|
|
|
|
|
smart_info=$(get_drive_smart_info "$device")
|
|
|
|
|
IFS='|' read -r type temp health model <<< "$smart_info"
|
|
|
|
|
printf "%-15s %-10s %-8s %-8s %-20s %-30s\n" "/dev/$device" "$size" "$type" "$temp" "$health" "$model"
|
|
|
|
|
done <<< "$nvme_drives"
|
|
|
|
|
fi
|
|
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# Show NVMe Drives only if present
|
2024-12-09 22:07:59 -05:00
|
|
|
nvme_drives=$(sudo nvme list | grep "^/dev")
|
2024-12-12 21:42:56 -05:00
|
|
|
if [ -n "$nvme_drives" ]; then
|
2024-12-12 21:48:11 -05:00
|
|
|
echo -e "\n=== NVMe Drives ===\n"
|
|
|
|
|
printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MODEL"
|
|
|
|
|
echo "------------------------------------------------------------"
|
2024-12-12 21:42:56 -05:00
|
|
|
echo "$nvme_drives" | awk '{printf "%-15s %-10s %-10s %-20s\n", $1, $6, "NVMe", $3}'
|
|
|
|
|
else
|
2024-12-12 21:48:11 -05:00
|
|
|
not_found+=("NVMe drives")
|
2024-12-12 21:42:56 -05:00
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# Show MMC Drives only if present
|
|
|
|
|
mmc_output=$(lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep "mmcblk" | sort)
|
2024-12-12 21:42:56 -05:00
|
|
|
if [ -n "$mmc_output" ]; then
|
2024-12-12 21:48:11 -05:00
|
|
|
echo -e "\n=== MMC Drives ===\n"
|
|
|
|
|
printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT"
|
|
|
|
|
echo "------------------------------------------------------------"
|
2024-12-12 21:42:56 -05:00
|
|
|
echo "$mmc_output"
|
|
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# Show SATA Drives only if present
|
2025-02-21 20:41:24 -05:00
|
|
|
sata_output=$(lsblk -d -o NAME,SIZE,TYPE,MOUNTPOINT | grep "disk" | grep -v "nvme" | grep -v "rbd" | sort | column -t)s
|
2024-12-12 21:42:56 -05:00
|
|
|
if [ -n "$sata_output" ]; then
|
2024-12-12 21:48:11 -05:00
|
|
|
echo -e "\n=== SATA Drives ===\n"
|
|
|
|
|
printf "%-15s %-10s %-10s %-20s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT"
|
|
|
|
|
echo "------------------------------------------------------------"
|
2024-12-12 21:42:56 -05:00
|
|
|
echo "$sata_output"
|
|
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# 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"
|
2024-12-09 22:07:59 -05:00
|
|
|
else
|
2024-12-12 21:48:11 -05:00
|
|
|
not_found+=("RBD devices")
|
2024-12-09 22:07:59 -05:00
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2024-12-12 21:48:11 -05:00
|
|
|
# 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[@]}"
|
2024-12-09 22:07:59 -05:00
|
|
|
fi
|