Add usage/help message and CLI argument parsing

Added comprehensive command-line interface with:
- -h, --help: Show usage information
- -v, --version: Show version
- -d, --debug: Enable debug output
- -s, --skip-smart: Skip SMART data collection (faster)
- --no-ceph: Skip Ceph OSD information
- --show-pci: Display PCI paths for debugging

The script now properly respects these flags throughout execution.

Fixes: #10

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 11:31:05 -05:00
parent 9d39332df3
commit 71a4e3b1fb

View File

@@ -5,6 +5,84 @@
# Maps physical drive bays to logical device names using PCI paths
#==============================================================================
VERSION="1.1.0"
#------------------------------------------------------------------------------
# show_usage
#
# Displays help message with usage information and available options.
#------------------------------------------------------------------------------
show_usage() {
cat << EOF
Drive Atlas v${VERSION} - Server Drive Mapping Tool
Maps physical drive bays to logical device names using PCI paths.
Displays visual chassis layouts and comprehensive drive information.
USAGE:
$(basename "$0") [OPTIONS]
OPTIONS:
-h, --help Show this help message and exit
-v, --version Show version information
-d, --debug Enable debug output (show drive mappings)
-s, --skip-smart Skip SMART data collection (faster)
--no-ceph Skip Ceph OSD information
--show-pci Show PCI paths in output
EXAMPLES:
$(basename "$0") # Normal run with all features
$(basename "$0") --skip-smart # Fast run without SMART data
$(basename "$0") --debug # Show mapping debug info
ENVIRONMENT VARIABLES:
DEBUG=1 Same as --debug flag
For more information, see: https://code.lotusguild.org/LotusGuild/driveAtlas
EOF
}
#------------------------------------------------------------------------------
# Command Line Argument Parsing
#------------------------------------------------------------------------------
SKIP_SMART=false
SKIP_CEPH=false
SHOW_PCI=false
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_usage
exit 0
;;
-v|--version)
echo "Drive Atlas v${VERSION}"
exit 0
;;
-d|--debug)
DEBUG=1
shift
;;
-s|--skip-smart)
SKIP_SMART=true
shift
;;
--no-ceph)
SKIP_CEPH=true
shift
;;
--show-pci)
SHOW_PCI=true
shift
;;
*)
echo "Unknown option: $1" >&2
echo "Use --help for usage information." >&2
exit 1
;;
esac
done
#------------------------------------------------------------------------------
# Dependency Checks
# Verifies required commands are available before running
@@ -313,21 +391,27 @@ get_storage_controllers() {
# Builds a global associative array mapping physical bay numbers to device names.
# Uses PCI paths from SERVER_MAPPINGS to resolve current device assignments.
#
# Sets: DRIVE_MAP (global associative array)
# Sets:
# DRIVE_MAP (global associative array)
# Keys: Bay identifiers (1, 2, ..., m2-1, m2-2, etc.)
# Values: Device names (sda, nvme0n1, etc.)
# BAY_TO_PCI_PATH (global associative array)
# Keys: Bay identifiers
# Values: PCI path strings (for --show-pci option)
#------------------------------------------------------------------------------
build_drive_map() {
local host="$(hostname)"
local mapping="${SERVER_MAPPINGS[$host]}"
# Declare global array directly instead of copying from local
# Declare global arrays directly
declare -g -A DRIVE_MAP=()
declare -g -A BAY_TO_PCI_PATH=()
if [[ -n "$mapping" ]]; then
while read -r path slot; do
[[ -z "$path" || -z "$slot" ]] && continue
BAY_TO_PCI_PATH[$slot]="$path"
if [[ -L "/dev/disk/by-path/$path" ]]; then
local drive="$(readlink -f "/dev/disk/by-path/$path" | sed 's/.*\///')"
DRIVE_MAP[$slot]="$drive"
@@ -509,11 +593,18 @@ esac
#------------------------------------------------------------------------------
# Build Ceph OSD cache (single query instead of per-device)
if [[ "$SKIP_CEPH" != true ]]; then
build_ceph_cache
fi
printf "\n=== Drive Details with SMART Status (by Bay Position) ===\n"
if [[ "$SHOW_PCI" == true ]]; then
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s %-40s\n" "BAY" "DEVICE" "SIZE" "TYPE" "TEMP" "HEALTH" "MODEL" "SERIAL" "CEPH OSD" "STATUS" "USAGE" "PCI PATH"
echo "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
else
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s\n" "BAY" "DEVICE" "SIZE" "TYPE" "TEMP" "HEALTH" "MODEL" "SERIAL" "CEPH OSD" "STATUS" "USAGE"
echo "----------------------------------------------------------------------------------------------------------------------------------------------------"
fi
# Build reverse map: device -> bay
declare -A DEVICE_TO_BAY
@@ -530,14 +621,25 @@ all_bays=$(printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^[0-9]+$' | sort -n; prin
for bay in $all_bays; do
device="${DRIVE_MAP[$bay]}"
if [[ -n "$device" && "$device" != "EMPTY" && -b "/dev/$device" ]]; then
size=$(lsblk -d -n -o SIZE "/dev/$device" 2>/dev/null)
smart_info=$(get_drive_smart_info "$device")
size="$(lsblk -d -n -o SIZE "/dev/$device" 2>/dev/null)"
# Get SMART info (or defaults if skipped)
if [[ "$SKIP_SMART" == true ]]; then
type="-"
temp="-"
health="-"
model="-"
serial="-"
else
smart_info="$(get_drive_smart_info "$device")"
IFS='|' read -r type temp health model serial <<< "$smart_info"
fi
# Check for Ceph OSD using cached data
osd_id="${CEPH_DEVICE_TO_OSD[$device]:-}"
osd_id="-"
ceph_status="-"
if [[ "$SKIP_CEPH" != true ]]; then
osd_id="${CEPH_DEVICE_TO_OSD[$device]:-}"
if [[ -n "$osd_id" ]]; then
# Get status from cached OSD tree data
osd_num="${osd_id#osd.}"
@@ -547,6 +649,7 @@ for bay in $all_bays; do
else
osd_id="-"
fi
fi
# Check mount points using lsblk (includes partitions)
# This catches both whole-device mounts and partition mounts (e.g., /dev/sda1)
@@ -566,8 +669,13 @@ for bay in $all_bays; do
fi
fi
if [[ "$SHOW_PCI" == true ]]; then
pci_path="${BAY_TO_PCI_PATH[$bay]:-}"
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s %-40s\n" "$bay" "/dev/$device" "$size" "$type" "$temp" "$health" "$model" "$serial" "$osd_id" "$ceph_status" "$usage" "$pci_path"
else
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s\n" "$bay" "/dev/$device" "$size" "$type" "$temp" "$health" "$model" "$serial" "$osd_id" "$ceph_status" "$usage"
fi
fi
done
# NVMe drives (only show unmapped ones - mapped NVMe drives appear in main table)