Add gather-hardware-info.sh — auto-detects most report fields
Deploy / deploy (push) Successful in 4s

Reads /proc, /sys, and common CLI tools (lscpu, lsblk, lspci, lsusb) to
print a YAML block matching data/schema.json: device model (DMI on x86,
/proc/device-tree/model on ARM SBCs), form factor (best-effort — battery
presence, DMI chassis type, device-tree presence), CPU, RAM, root storage
type/size, WiFi chip (PCI, then USB, then falls back to driver name rather
than guessing wrong), ethernet. Fields it can't detect (archy_version,
install_method, status) are left as clearly-marked TODOs rather than
guessed. Local-only — no network calls, changes nothing.

Tested for real on this box (a QEMU VM): correctly identified it as a VM,
correctly fell back to "other" with a TODO for form_factor rather than
guessing, output validated as parseable YAML. Passes shellcheck clean.

Linked from the homepage, report.html, and CONTRIBUTING.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 02:49:02 +00:00
co-authored by Claude Sonnet 5
parent dcc09ddee4
commit 5df5b50dca
5 changed files with 166 additions and 7 deletions
+14 -7
View File
@@ -1,6 +1,10 @@
# Contributing to ArchyHCL # Contributing to ArchyHCL
Two ways to add a report, pick whichever's easier for you. Two ways to add a report, pick whichever's easier for you. Either way,
running [`gather-hardware-info.sh`](https://hcl.archipelago-foundation.org/gather-hardware-info.sh)
on the machine you tested first is the easiest way to get accurate
CPU/RAM/storage/WiFi-chip values — it's local-only (reads `/proc`/`/sys`,
no network calls), read it before you run it like any script.
## Option A — use the report form (no git needed) ## Option A — use the report form (no git needed)
@@ -31,8 +35,9 @@ supported no-git path, not the raw "New Issue" button.)
This fails loudly (and tells you exactly which field) if anything's This fails loudly (and tells you exactly which field) if anything's
wrong — same idea as [archy](https://source.archipelago-foundation.org/lfg2025/archy)'s wrong — same idea as [archy](https://source.archipelago-foundation.org/lfg2025/archy)'s
own `scripts/validate-app-manifest.sh`. own `scripts/validate-app-manifest.sh`.
4. Open the PR. Once merged, `scripts/build.py` regenerates `site/data.json` 4. Open the PR. Once merged, deployment is automatic — a CI job rebuilds
and the site picks it up. `site/data.json` and pushes it live within seconds, no manual step
needed.
## Updating an existing report ## Updating an existing report
@@ -44,10 +49,12 @@ report is.
## What makes a good report ## What makes a good report
- Be exact about the WiFi chip if you can (`iwconfig`/`lspci` on Linux, - Be exact about the WiFi chip if you can (`gather-hardware-info.sh` above
Device Manager on Windows if you dual-booted to check). "Realtek" alone gets this right on most Linux hardware; `iwconfig`/`lspci` by hand
isn't as useful as "Realtek RTL8821CE" — chip-specific driver issues are otherwise, Device Manager on Windows if you dual-booted to check).
the single most common thing this list exists to surface. "Realtek" alone isn't as useful as "Realtek RTL8821CE" — chip-specific
driver issues are the single most common thing this list exists to
surface.
- If `status` is `partial` or `broken`, describe *what* broke and *how you - If `status` is `partial` or `broken`, describe *what* broke and *how you
noticed* (crash on boot? WiFi drops under load? specific app won't noticed* (crash on boot? WiFi drops under load? specific app won't
start?) — "doesn't work" isn't actionable for the next person. start?) — "doesn't work" isn't actionable for the next person.
+142
View File
@@ -0,0 +1,142 @@
#!/usr/bin/env bash
# gather-hardware-info.sh — collects the fields ArchyHCL's report form asks
# for and prints a YAML block matching data/schema.json, ready to paste into
# https://hcl.archipelago-foundation.org/report.html or a PR.
#
# Read before you run, like any script from the internet:
# https://source.archipelago-foundation.org/ssmithx/ArchyHCL/src/branch/main/site/gather-hardware-info.sh
#
# Local-only: reads /proc, /sys, and a few common CLI tools. Makes no
# network calls and changes nothing on the system. Some fields (WiFi chip
# on non-PCI hardware, device model on some boards) can't be detected
# reliably everywhere — those are left as TODO rather than guessed wrong.
#
# Usage: ./gather-hardware-info.sh (or: bash gather-hardware-info.sh)
set -uo pipefail
have() { command -v "$1" >/dev/null 2>&1; }
# --- device model ---
device_model="TODO — e.g. \"Lenovo ThinkPad T430\""
if [ -r /proc/device-tree/model ]; then
# Raspberry Pi and most other ARM SBCs expose a clean model string here,
# null-terminated.
device_model="$(tr -d '\0' < /proc/device-tree/model)"
elif [ -r /sys/class/dmi/id/sys_vendor ] && [ -r /sys/class/dmi/id/product_name ]; then
vendor="$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null)"
product="$(cat /sys/class/dmi/id/product_name 2>/dev/null)"
if [ -n "$vendor" ] && [ -n "$product" ]; then
device_model="$vendor $product"
fi
fi
# --- form factor (best-effort guess — double-check this one) ---
form_factor="other # TODO: couldn't guess confidently, pick laptop|desktop|mini-pc|sbc|server|other"
if [ -r /proc/device-tree/model ]; then
form_factor="sbc"
elif ls /sys/class/power_supply/BAT* >/dev/null 2>&1; then
form_factor="laptop"
elif [ -r /sys/class/dmi/id/chassis_type ]; then
case "$(cat /sys/class/dmi/id/chassis_type 2>/dev/null)" in
8|9|10|14) form_factor="laptop" ;; # Portable/Laptop/Notebook/Sub-Notebook
3|4|6|7) form_factor="desktop" ;; # Desktop/Low Profile Desktop/Mini Tower/Tower
35|36) form_factor="mini-pc" ;; # Small Form Factor variants some vendors use
23) form_factor="server" ;; # Rack Mount Chassis
esac
fi
# --- CPU ---
if have lscpu; then
cpu="$(lscpu | awk -F: '/^Model name/ {print $2; exit}' | sed 's/^ *//')"
fi
if [ -z "${cpu:-}" ]; then
cpu="$(awk -F: '/^model name/ {print $2; exit}' /proc/cpuinfo | sed 's/^ *//')"
fi
if [ -z "${cpu:-}" ]; then
# ARM boards often don't set "model name" — fall back to the SoC line.
cpu="$(awk -F: '/^Hardware|^Model/ {print $2; exit}' /proc/cpuinfo | sed 's/^ *//')"
fi
[ -z "${cpu:-}" ] && cpu="TODO — could not detect, check \`lscpu\` or \`cat /proc/cpuinfo\`"
# --- RAM (rounded up to the nearest whole GB) ---
ram_kb="$(awk '/MemTotal/ {print $2}' /proc/meminfo)"
ram_gb=$(( (ram_kb + 1048575) / 1048576 ))
# --- root filesystem storage: type + size ---
storage_type="TODO"
storage_size_gb="TODO"
if have lsblk && have findmnt; then
root_src="$(findmnt -no SOURCE / 2>/dev/null || true)"
root_dev="$(lsblk -no PKNAME "$root_src" 2>/dev/null || true)"
[ -z "$root_dev" ] && root_dev="$(basename "${root_src:-}" 2>/dev/null | sed -E 's/p?[0-9]+$//')"
if [ -n "$root_dev" ] && [ -b "/dev/$root_dev" ]; then
size_bytes="$(lsblk -bno SIZE "/dev/$root_dev" 2>/dev/null | head -1)"
if [ -n "$size_bytes" ]; then
storage_size_gb=$(( size_bytes / 1073741824 ))
fi
case "$root_dev" in
nvme*) storage_type="nvme" ;;
mmcblk*) storage_type="emmc" ;;
*)
if [ -r "/sys/block/$root_dev/queue/rotational" ]; then
if [ "$(cat "/sys/block/$root_dev/queue/rotational")" = "0" ]; then
storage_type="ssd"
else
storage_type="hdd"
fi
fi
;;
esac
fi
fi
# --- WiFi chip: try PCI, then USB, then fall back to the driver name ---
wifi_chip="none"
wifi_iface=""
for w in /sys/class/net/*/wireless; do
[ -d "$w" ] || continue
wifi_iface="$(basename "$(dirname "$w")")"
break
done
if [ -n "$wifi_iface" ]; then
if have lspci; then
wifi_chip="$(lspci | grep -iE 'network controller|wireless' | head -1 | sed -E 's/^[0-9a-f:.]+ [^:]+: //')"
fi
if [ -z "$wifi_chip" ] && have lsusb; then
wifi_chip="$(lsusb | grep -iE 'wireless|wifi|802\.11' | head -1 | sed -E 's/^Bus [0-9]+ Device [0-9]+: ID [0-9a-f]{4}:[0-9a-f]{4} //')"
fi
if [ -z "$wifi_chip" ] && [ -r "/sys/class/net/$wifi_iface/device/uevent" ]; then
driver="$(awk -F= '/^DRIVER=/ {print $2}' "/sys/class/net/$wifi_iface/device/uevent")"
[ -n "$driver" ] && wifi_chip="driver: $driver (chip model not auto-detected — check \`lsusb\`/\`lspci\` by hand)"
fi
[ -z "$wifi_chip" ] && wifi_chip="TODO — wireless interface $wifi_iface found but chip not identified"
fi
# --- Ethernet chip (best-effort) ---
ethernet=""
if have lspci; then
ethernet="$(lspci | grep -i 'ethernet controller' | head -1 | sed -E 's/^[0-9a-f:.]+ [^:]+: //')"
fi
today="$(date +%F 2>/dev/null || echo "TODO")"
cat <<YAML
# Auto-gathered by gather-hardware-info.sh — check every field, especially
# any marked TODO, then paste this into:
# https://hcl.archipelago-foundation.org/report.html (fill the form instead — easiest)
# or add it directly as data/reports/<slug>.yml in a PR — see CONTRIBUTING.md
device_model: "$device_model"
form_factor: $form_factor
cpu: "$cpu"
ram_gb: $ram_gb
storage:
type: $storage_type
size_gb: $storage_size_gb
wifi_chip: "$wifi_chip"
$( [ -n "$ethernet" ] && echo "ethernet: \"$ethernet\"" )
archy_version: "TODO — e.g. 1.8.10-alpha"
install_method: TODO # usb-iso | netboot | existing-os-script | other
status: TODO # working | partial | broken
tested_date: "$today"
YAML
+7
View File
@@ -14,6 +14,13 @@
Tested Archipelago on your own hardware? <a href="report.html">Report it</a> — Tested Archipelago on your own hardware? <a href="report.html">Report it</a> —
takes two minutes and helps the next person know what to expect before they buy or repurpose a machine. takes two minutes and helps the next person know what to expect before they buy or repurpose a machine.
</p> </p>
<p class="cta-secondary">
Not sure of your exact CPU/WiFi chip/etc.? Run
<a href="gather-hardware-info.sh">this script</a> on the machine you
tested — <code>bash gather-hardware-info.sh</code> — it prints most of
the fields for you, ready to paste into the form above. Local-only, no
network calls, <a href="gather-hardware-info.sh" target="_blank" rel="noopener">read it</a> before you run it like you should with any script.
</p>
</header> </header>
<main> <main>
+1
View File
@@ -10,6 +10,7 @@
<header> <header>
<h1><a href="index.html">ArchyHCL</a></h1> <h1><a href="index.html">ArchyHCL</a></h1>
<p>Fill this in, hit submit — it opens a pre-filled issue on Gitea with everything formatted and ready for a maintainer to merge. You'll still need a (free) Gitea account to actually post it.</p> <p>Fill this in, hit submit — it opens a pre-filled issue on Gitea with everything formatted and ready for a maintainer to merge. You'll still need a (free) Gitea account to actually post it.</p>
<p>Not sure of your exact CPU/WiFi chip/storage? Run <a href="gather-hardware-info.sh">gather-hardware-info.sh</a> on the machine you tested first — it prints most of these fields for you.</p>
</header> </header>
<main> <main>
+2
View File
@@ -38,6 +38,8 @@ a:hover { color: var(--accent); }
header p { color: var(--muted); max-width: 70ch; } header p { color: var(--muted); max-width: 70ch; }
header .cta { color: var(--text); } header .cta { color: var(--text); }
header .cta-secondary { color: var(--muted); font-size: 0.85rem; max-width: 70ch; }
header .cta-secondary code { background: var(--panel); padding: 0.1rem 0.35rem; border-radius: 3px; color: var(--text); }
.controls { .controls {
display: flex; display: flex;