clawdie-iso/live/operator-session/hw-report
Sam & Claude efc15add8b Expand live XFCE diagnostics in hw-report
Capture xsession errors, build manifest/assets, Colibri enable state, deeper icon-theme paths, and clear mixer HDMI pinning in the visual guard.\n\nChecks: sh -n live/operator-session/hw-report live/operator-session/clawdie-xfce-visuals-guard.sh; ./scripts/check-format.sh; git diff --check.
2026-06-01 21:37:31 +02:00

394 lines
16 KiB
Bash
Executable file

#!/bin/sh
# Collect a local hardware report for Clawdie live-USB support and future
# custom ISO builds. This command never uploads unless explicitly requested.
set -u
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH
usage() {
cat <<'EOF'
Usage: hw-report [--upload-public-probe] [--no-smart]
Collect a local hardware diagnostics bundle under /home/clawdie/hw-reports
when that home directory exists, otherwise under $HOME/hw-reports.
Options:
--upload-public-probe Also run hw-probe -all -upload. This submits an
anonymous public report to bsd-hardware.info.
--no-smart Skip smartctl disk probes.
-h, --help Show this help.
Recommended live-USB invocation:
mdo -u root hw-report
EOF
}
_upload_public_probe="NO"
_run_smart="YES"
while [ "$#" -gt 0 ]; do
case "$1" in
--upload-public-probe)
_upload_public_probe="YES"
;;
--no-smart)
_run_smart="NO"
;;
-h|--help)
usage
exit 0
;;
*)
echo "ERROR: unknown option: $1" >&2
usage >&2
exit 2
;;
esac
shift
done
if [ "$(id -u)" -ne 0 ]; then
echo "WARNING: not running as root; some hardware data will be incomplete." >&2
echo "Recommended: mdo -u root hw-report" >&2
fi
_stamp="$(date -u '+%Y%m%dT%H%M%SZ')"
_host="$(hostname 2>/dev/null || echo clawdie-live)"
_report_name="hw-report-${_host}-${_stamp}"
if [ -d /home/clawdie ]; then
_base="${CLAWDIE_HW_REPORT_DIR:-/home/clawdie/hw-reports}"
else
_base="${CLAWDIE_HW_REPORT_DIR:-${HOME:-/root}/hw-reports}"
fi
_report_dir="${_base}/${_report_name}"
_raw_dir="${_report_dir}/raw"
_logs_dir="${_report_dir}/logs"
mkdir -p "${_raw_dir}" "${_logs_dir}"
_log="${_report_dir}/collection.log"
: > "${_log}"
note() {
printf '%s %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*" | tee -a "${_log}"
}
have() {
command -v "$1" >/dev/null 2>&1
}
run_capture() {
_name="$1"
shift
_out="${_raw_dir}/${_name}.txt"
note "collect ${_name}: $*"
{
printf '# command: %s\n' "$*"
printf '# collected_utc: %s\n\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
"$@"
} > "${_out}" 2>&1
_rc=$?
printf '\n# exit_status: %s\n' "${_rc}" >> "${_out}"
if [ "${_rc}" -ne 0 ]; then
note "WARN ${_name} exited ${_rc}"
fi
return 0
}
run_shell_capture() {
_name="$1"
_cmd="$2"
_out="${_raw_dir}/${_name}.txt"
note "collect ${_name}: ${_cmd}"
{
printf '# command: %s\n' "${_cmd}"
printf '# collected_utc: %s\n\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
/bin/sh -c "${_cmd}"
} > "${_out}" 2>&1
_rc=$?
printf '\n# exit_status: %s\n' "${_rc}" >> "${_out}"
if [ "${_rc}" -ne 0 ]; then
note "WARN ${_name} exited ${_rc}"
fi
return 0
}
run_if_present() {
_cmd="$1"
_name="$2"
shift 2
if have "${_cmd}"; then
run_capture "${_name}" "${_cmd}" "$@"
else
note "skip ${_name}: ${_cmd} not found"
fi
}
run_shell_if_present() {
_cmd="$1"
_name="$2"
_script="$3"
if have "${_cmd}"; then
run_shell_capture "${_name}" "${_script}"
else
note "skip ${_name}: ${_cmd} not found"
fi
}
json_escape() {
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
}
note "start ${_report_name}"
cat > "${_report_dir}/README.txt" <<'EOF'
Clawdie hardware report bundle
This is a local diagnostics bundle for FreeBSD/Clawdie live-USB support and
future custom ISO builds. It is not uploaded automatically.
Privacy notes:
- This bundle may contain hostnames, MAC addresses, disk model/serial strings,
USB/PCI IDs, kernel messages, local network interface state, Xorg/SDDM log
details, device names, and monitor EDID or serial-like strings.
- Review before sharing.
- Public hw-probe upload only happens when hw-report is run with
--upload-public-probe.
EOF
run_capture uname-a uname -a
run_if_present freebsd-version freebsd-version-kru -kru
run_capture hostname hostname
run_capture date-utc date -u '+%Y-%m-%dT%H:%M:%SZ'
run_if_present uptime uptime
run_if_present pciconf pciconf-lv -lv
run_if_present pciconf pciconf-lvbce -lvbce
run_if_present usbconfig usbconfig
run_if_present usbconfig usb-device-desc dump_device_desc
run_if_present usbconfig usb-all-desc dump_all_desc
run_if_present devinfo devinfo-rv -rv
run_if_present dmidecode dmidecode
run_if_present service dbus-status dbus onestatus
run_if_present service sddm-status sddm onestatus
run_if_present kldstat kldstat
run_if_present kldstat kldstat-v -v
run_if_present dmesg dmesg
run_shell_capture dmesg-hardware-filter "dmesg | egrep -i 'drm|kms|amdgpu|i915|radeon|nvidia|firmware|wifi|wlan|iwm|iwlwifi|rtwn|urtwn|run|otus|mt76|usb|uhub|ure|ue[0-9]|realtek|rtl|bluetooth|ubt|bcm|cypress|webcam|video|hid|iichid|hms|hmt|elan|touch|acpi|battery|powerd'"
run_shell_capture dmesg-boot "for f in /var/run/dmesg.boot; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture xorg-var-logs "for f in /var/log/Xorg.*.log*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture xorg-user-logs "for f in /home/clawdie/.local/share/xorg/Xorg.*.log*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture xsession-errors "for f in /home/clawdie/.xsession-errors /home/clawdie/.xsession-errors.old; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture var-log-messages "for f in /var/log/messages*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; case \"\$f\" in *.gz) zcat \"\$f\";; *.bz2) bzcat \"\$f\";; *.xz) xzcat \"\$f\";; *.zst) zstdcat \"\$f\";; *) cat \"\$f\";; esac; echo; done"
run_shell_capture sddm-log-files "for f in /var/log/sddm.log; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture sddm-config "for f in /usr/local/etc/sddm.conf /usr/local/etc/sddm.conf.d/*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture loader-conf-files "for f in /boot/loader.conf /boot/loader.conf.local; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_if_present kenv kenv
run_shell_capture xorg-config-snippets "for f in /usr/local/etc/X11/xorg.conf.d/* /etc/X11/xorg.conf.d/* /usr/local/share/X11/xorg.conf.d/*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_if_present ifconfig ifconfig-a -a
run_if_present netstat netstat-rn -rn
run_shell_capture resolver-state "ls -l /etc/resolv.conf 2>/dev/null || true; readlink /etc/resolv.conf 2>/dev/null || true; cat /etc/resolv.conf 2>/dev/null || true"
run_shell_capture wlan-devices "sysctl net.wlan.devices"
run_shell_capture rc-conf-live "grep -E '^(hostname|kld_list|sshd_enable|tailscaled_enable|avahi_daemon_enable|pf_enable|sddm_enable|webcamd_enable|powerdxx_enable|colibri_daemon_enable|clawdie_live_|performance_cx_lowest|economy_cx_lowest|dumpdev_enable)' /etc/rc.conf || true"
run_if_present service service-enabled -e
run_if_present sysctl sysctl-hw hw
run_if_present sysctl sysctl-machdep machdep
run_shell_capture sysctl-selected "sysctl hw.acpi hw.dri kern.disks kern.geom net.wlan.devices dev.cpu 2>/dev/null || true"
run_shell_capture sysctl-drm-hw-dri "sysctl dev.drm hw.dri 2>/dev/null || true"
run_if_present service powerdxx-status powerdxx status
run_if_present sysctl snd-default-unit hw.snd.default_unit
run_if_present sysctl acpi-acline hw.acpi.acline
run_if_present sysctl acpi-cx-lowest hw.acpi.cpu.cx_lowest
run_if_present sysctl acpi-video-brightness hw.acpi.video.lcd0.brightness
run_shell_capture sysctl-input-stack "sysctl kern.evdev dev.iichid dev.hidbus dev.hms dev.hmt dev.hkbd dev.hconf dev.ig4 dev.psm dev.atkbd dev.uhid hw.psm 2>/dev/null || true"
run_if_present service moused-status moused onestatus
run_if_present gpart gpart-show show
run_if_present geom geom-disk-list disk list
run_if_present camcontrol camcontrol-devlist devlist
run_if_present nvmecontrol nvmecontrol-devlist devlist
run_if_present df df-h -h
run_if_present mount mount
run_if_present zpool zpool-list list
run_if_present zfs zfs-list list
if [ "${_run_smart}" = "YES" ] && have smartctl; then
_disks="$(sysctl -n kern.disks 2>/dev/null || true)"
if [ -n "${_disks}" ]; then
for _disk in ${_disks}; do
case "${_disk}" in
md*|cd*)
note "skip smartctl-${_disk}: virtual/removable class"
;;
*)
run_capture "smartctl-${_disk}" smartctl -a "/dev/${_disk}"
;;
esac
done
else
note "skip smartctl: kern.disks empty"
fi
else
note "skip smartctl: disabled or smartctl not found"
fi
run_if_present lspci lspci-nn -nn
run_if_present lsusb lsusb
run_if_present lscpu lscpu
run_if_present lsblk lsblk
run_if_present hwstat hwstat
run_shell_if_present usbhid-dump usbhid-dump-version "usbhid-dump --help 2>&1 | head -40"
run_if_present cat clawdie-live-gpu-log /var/log/clawdie-live-gpu.log
run_if_present cat clawdie-noblank-guard-log /home/clawdie/.clawdie-noblank-guard.log
run_if_present cat clawdie-xfce-visuals-guard-log /home/clawdie/.clawdie-xfce-visuals-guard.log
run_if_present cat clawdie-touchpad-guard-log /home/clawdie/.clawdie-touchpad-guard.log
run_if_present cat sndstat /dev/sndstat
run_if_present mixer mixer-s -s
run_if_present v4l2-ctl v4l2-list-devices --list-devices
run_shell_capture video-devices "ls -l /dev/video* 2>/dev/null || true"
run_shell_capture dri-devices "ls -l /dev/dri /dev/dri/* 2>/dev/null || true"
run_shell_capture input-device-nodes "ls -l /dev/input /dev/input/* /dev/uhid* /dev/atp* 2>/dev/null || true"
run_if_present xset xset-q q
run_shell_if_present xfconf-query xfce4-power-manager "xfconf-query -c xfce4-power-manager -l -v 2>/dev/null || true"
run_shell_if_present xfconf-query xfce4-panel "xfconf-query -c xfce4-panel -l -v 2>/dev/null || true"
run_shell_if_present xfconf-query xfce4-desktop "xfconf-query -c xfce4-desktop -l -v 2>/dev/null || true"
run_shell_if_present xfconf-query xsettings "xfconf-query -c xsettings -l -v 2>/dev/null || true"
run_shell_if_present xfconf-query xfce4-pointers "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xfconf-query -c pointers -l -v 2>/dev/null || xfconf-query -c pointers -l -v 2>/dev/null || true"
run_shell_capture xfce-perchannel-xml "for f in /home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture xfce-panel-launchers "find /home/clawdie/.config/xfce4/panel -maxdepth 4 -type f -print -exec sed -n '1,80p' {} \\; 2>/dev/null || true"
run_shell_capture icon-theme-dirs "find /usr/local/share/icons -maxdepth 4 -type f \( -name 'icon-theme.cache' -o -name 'clawdie-start.*' \) -print 2>/dev/null || true"
run_shell_capture clawdie-iso-assets "find /usr/local/share/clawdie-iso -maxdepth 4 -type f -ls 2>/dev/null || true; for f in /usr/local/share/clawdie-iso/build-manifest.json; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done"
run_shell_capture colibri-service-state "service colibri_daemon status 2>&1 || true; egrep -n '^(command|command_args|procname)=' /usr/local/etc/rc.d/colibri_daemon 2>/dev/null || true; sysrc -n colibri_daemon_enable 2>/dev/null || true"
if [ -f /home/clawdie/.Xauthority ]; then
run_shell_if_present xinput xinput-list "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xinput list 2>/dev/null || true"
run_shell_if_present xinput xinput-list-props "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority sh -c 'for id in \$(xinput list --id-only 2>/dev/null); do echo \"===== device \$id =====\"; xinput list-props \"\$id\"; echo; done' || true"
run_shell_if_present xrandr xrandr-verbose "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xrandr --verbose 2>/dev/null || true"
run_shell_if_present glxinfo glxinfo-B "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority glxinfo -B 2>/dev/null || true"
fi
run_shell_if_present libinput libinput-list-devices "libinput list-devices 2>/dev/null || true"
run_if_present vulkaninfo vulkaninfo-summary --summary
if have vulkaninfo && [ -f /home/clawdie/.Xauthority ]; then
run_shell_capture vulkaninfo-summary-display0 "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority vulkaninfo --summary"
fi
run_if_present pkg pkg-info info
run_if_present pkg pkg-version version
run_if_present pkg pkg-audit audit
run_if_present hw-probe hw-probe-all -all
if [ "${_upload_public_probe}" = "YES" ]; then
if have hw-probe; then
run_capture hw-probe-all-upload hw-probe -all -upload
else
note "skip hw-probe public upload: hw-probe not found"
fi
else
note "public hw-probe upload not requested"
fi
_public_probe_urls=""
_public_probe_url=""
_upload_output="${_raw_dir}/hw-probe-all-upload.txt"
if [ -f "${_upload_output}" ]; then
_public_probe_urls="$(grep -Eo 'https?://[^[:space:]<>"'"'"']+' "${_upload_output}" | grep -E 'bsd-hardware\.info|linux-hardware\.org' | sort -u || true)"
_public_probe_url="$(printf '%s\n' "${_public_probe_urls}" | sed -n '1p')"
fi
_freebsd="$(freebsd-version -kru 2>/dev/null | tr '\n' ' ' | sed 's/[[:space:]]*$//')"
_gpu="$(pciconf -lv 2>/dev/null | grep -B3 -A4 -E 'VGA|display' | sed -n '1,12p')"
_wlan="$(sysctl -n net.wlan.devices 2>/dev/null || true)"
_disks="$(sysctl -n kern.disks 2>/dev/null || true)"
cat > "${_report_dir}/summary.txt" <<EOF
Clawdie hardware report
=======================
Report: ${_report_name}
Collected UTC: ${_stamp}
Host: ${_host}
FreeBSD: ${_freebsd}
Output directory: ${_report_dir}
Public hardware probe URL: ${_public_probe_url:-not uploaded or not reported by hw-probe}
Wireless parent devices:
${_wlan:-none reported}
Kernel disks:
${_disks:-none reported}
Display devices, first lines:
${_gpu:-none reported}
Share only after review. The bundle may include MAC addresses, serial strings,
local hostnames, and kernel/network state.
EOF
cat > "${_report_dir}/summary.json" <<EOF
{
"schema": "clawdie.hardware-report.v1",
"report_name": "$(json_escape "${_report_name}")",
"collected_utc": "$(json_escape "${_stamp}")",
"host": "$(json_escape "${_host}")",
"freebsd": "$(json_escape "${_freebsd}")",
"wlan_devices": "$(json_escape "${_wlan}")",
"kernel_disks": "$(json_escape "${_disks}")",
"public_probe_upload_requested": "${_upload_public_probe}",
"public_probe_url": "$(json_escape "${_public_probe_url}")",
"smart_probe_requested": "${_run_smart}",
"privacy_note": "local report; review before sharing"
}
EOF
_archive="${_base}/${_report_name}.tar.gz"
run_shell_capture report-file-list "find '${_report_dir}' -type f | sort"
if tar -czf "${_archive}" -C "${_base}" "${_report_name}" >> "${_log}" 2>&1; then
note "archive ${_archive}"
else
note "WARN archive failed: ${_archive}"
fi
if [ -d /home/clawdie ] && id clawdie >/dev/null 2>&1; then
chown -R clawdie:clawdie "${_base}" 2>/dev/null || true
fi
cat <<EOF
Clawdie hardware report complete.
Summary:
${_report_dir}/summary.txt
JSON:
${_report_dir}/summary.json
Archive:
${_archive}
EOF
if [ "${_upload_public_probe}" = "YES" ]; then
if [ -n "${_public_probe_url}" ]; then
cat <<EOF
Public hardware probe:
${_public_probe_url}
EOF
else
cat <<EOF
Public hardware probe upload was requested, but no public URL was detected.
Inspect:
${_upload_output}
EOF
fi
else
cat <<EOF
Review before sharing. To include a public bsd-hardware.info probe URL, rerun:
mdo -u root hw-report --upload-public-probe
EOF
fi
exit 0