Add gather-hardware-info.sh — auto-detects most report fields
Deploy / deploy (push) Successful in 4s
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:
+14
-7
@@ -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.
|
||||||
|
|||||||
Executable
+142
@@ -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
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user