#!/bin/sh
# hw-read — the root half of the node's hardware-fault report (registry v3.40).
#
# Why:  SMART and the BMC are readable only by root, and the agent runs as esto.
#       sudoers cannot safely constrain arguments (smartctl -s off, ipmitool raw …
#       are writes), so the grant names this wrapper and the wrapper owns the
#       argument check: a fixed verb set, one validated disk name, nothing else.
# What: smart <disk>      smartctl -j -H -A /dev/<disk>  (disk = [a-z0-9]+ with a
#                         /sys/block/<disk>/device entry)
#       ipmi-load         modprobe ipmi_devintf ipmi_si (the agent's first IPMI read)
#       ipmi-sel          ipmitool sel info
#       ipmi-sdr psu|fan|temp   ipmitool -c sdr type <Power Supply|Fan|Temperature>
#       ipmi-chassis      ipmitool chassis status
#       Every verb is read-only. Any other input exits 2.
# Used: transcoder-node agent (internal/hwfaults) via
#       `sudo -n /usr/lib/transcoder-node/hw-read …` (/etc/sudoers.d/transcoder-node).
set -eu
PATH=/usr/sbin:/usr/bin:/sbin:/bin
export PATH

usage() { echo "hw-read: usage: smart <disk> | ipmi-load | ipmi-sel | ipmi-sdr psu|fan|temp | ipmi-chassis" >&2; exit 2; }

[ $# -ge 1 ] || usage
case "$1" in
smart)
    [ $# -eq 2 ] || usage
    case "$2" in ''|*[!a-z0-9]*) usage ;; esac
    [ -e "/sys/block/$2/device" ] || { echo "hw-read: no such disk: $2" >&2; exit 2; }
    exec smartctl -j -H -A "/dev/$2"
    ;;
ipmi-load)
    [ $# -eq 1 ] || usage
    exec modprobe -a ipmi_devintf ipmi_si
    ;;
ipmi-sel)
    [ $# -eq 1 ] || usage
    exec ipmitool sel info
    ;;
ipmi-sdr)
    [ $# -eq 2 ] || usage
    case "$2" in
    psu) exec ipmitool -c sdr type "Power Supply" ;;
    fan) exec ipmitool -c sdr type "Fan" ;;
    temp) exec ipmitool -c sdr type "Temperature" ;;
    *) usage ;;
    esac
    ;;
ipmi-chassis)
    [ $# -eq 1 ] || usage
    exec ipmitool chassis status
    ;;
*) usage ;;
esac
