#!/bin/sh if [ "$(whoami)" != "root" ]; then echo "This script is intended to run as root. Exiting" >&2 exit 1 fi for cmd in lshw jq; do if ! command -v $cmd > /dev/null; then echo "Please install $cmd. Exiting." >&2 exit 1 fi done if [ "$1" = "" ]; then echo "Usage: export-hardware.sh PATH_TO_OUTPUT" >&2 exit 1 fi output=$1 if [ -d "$1" ]; then echo "$1 is a directory and cannot be used as output. Exiting." >&2 exit 1 fi # We extract hardware details only once, as it can be somewhat expensive/slow. echo "Extracting hardware informations.... " hardware=$(lshw -json) hostname=$(hostname --short) components=$(echo "$hardware" | jq -r -c '..|.children?|select(.!=null)|.[]') echo "--- OK" print_server_component () { class=$(echo "$@"| jq -j -c .class) if echo "system processor memory power bus" | grep -w -q "$class"; then # Motherboards are 'bus' class and what **seem** to be consistent (from a # server + my laptop) 'Motherboard' description. if [ "$class" = "bus" ] && [ "$(echo "$@"| jq -j -c .description)" != "Motherboard" ]; then return fi serial=$(echo "$@"| jq -j -c '.serial // "-"') name='\(.description // .product)' manufacturer='\(.vendor // "-")' model='\(.product // "-")' case "$class" in "power") name="$name (slot: \\(.slot // \"-\"))" ;; "system") # Ignore irrelevant PnP (and probably others) devices. if [ "$serial" = "-" ]; then return fi ;; "memory") # Ignore CPU cache (= memory entries without serial number). if [ "$serial" = "-" ]; then return fi # Extract size of RAM sticks. units=$(echo "$@"| jq -j -c .units) size=$(echo "$@"| jq -j -c .size) if [ "$units" = "bytes" ]; then model="\(.product) ($(((size / 1024 / 1024 / 1024 ))) GB)" else model='\(.product) (\(.size) \(.units),)' fi ;; esac echo "$@" | jq -j -c ".|\"| $class | $name | $manufacturer | $model | $serial | \n\"" fi } get_disk_details () { product=$(echo "$@" | jq -j -c .product) size=$(echo "$@" | jq -j -c .size) units=$(echo "$@" | jq -j -c .units) serial=$(echo "$@" | jq -j -c .serial) if [ "$units" = "bytes" ]; then size=$(((size / 1024 / 1024 / 1024))) units='GB' fi cat <<- EOF $product ($serial, $size $units) EOF } ### Output ### touch "$output" echo "Generating system section... " cat <<- EOF > "$output" # Host: $hostname Extracted on $(date -I) by the [hardware-to-mkd script](https://code.recycled.cloud/RecycledCloud/tools/src/branch/master/hardware-to-mkd). ## System | Class | Name | Manufacturer | Model | Serial | |-------|------|--------------|-------|--------| $(print_server_component "$hardware") EOF echo "$components" | while read -r component; do print_server_component "$component" >> "$output" done echo "--- OK" echo "Generating disks section... " cat <<- EOF >> "$output" ## Disks | Disk | |------| EOF echo "$components" | while read -r component; do class=$(echo "$component"| jq -j -c .class) if [ "$class" = "disk" ]; then echo "| $(get_disk_details "$component") |" >> "$output" fi done echo "--- OK" echo "Generating NICs section... " cat <<- EOF >> "$output" ## NICs | Interface | MAC | |-----------|-----| EOF echo "$components" | while read -r component; do class=$(echo "$component"| jq -j -c .class) if [ "$class" = "network" ]; then serial=$(echo "$component"| jq -j -c '.serial // "-"') iface=$(ip -j l | jq -r -c ".[] | select(.address == \"$serial\") | .ifname") echo "| $iface | $serial |" >> "$output" fi done echo "--- OK"