From f9c1e2d40e56f2bfbfbac78209d6ee921569cee8 Mon Sep 17 00:00:00 2001 From: smill Date: Tue, 29 Sep 2026 21:58:55 -0400 Subject: [PATCH] doctor: report exactly what is missing and how to install it Lists each dnf-provisioned tool and app with its package, flags bundled dependencies (PassMark, llama-bench, model, matplotlib) and prints a RESULT verdict with a ready-to-run dnf install command. App packages are now included in the missing/package accounting. --- run-benchmarks.sh | 85 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/run-benchmarks.sh b/run-benchmarks.sh index 177c688..f42249d 100755 --- a/run-benchmarks.sh +++ b/run-benchmarks.sh @@ -139,6 +139,8 @@ PKG_FOR_TOOL_CMD="7z:7zip openssl:openssl fio:fio stress-ng:stress-ng \ sensors:lm_sensors turbostat:kernel-tools cpupower:cpupowerutils \ glmark2:glmark2 vkmark:vkmark glxinfo:mesa-demos vulkaninfo:vulkan-tools \ sysbench:sysbench" +# App workloads map to their own packages; included in the missing/pkg checks. +PKG_FOR_APP_CMD="libreoffice:libreoffice-writer inkscape:inkscape gegl:gegl04-tools" missing_tools() { # prints tool names whose command is absent local pair cmd @@ -147,9 +149,16 @@ missing_tools() { # prints tool names whose command is absent have "$cmd" || printf '%s\n' "$cmd" done } +missing_apps() { + local pair cmd + for pair in $PKG_FOR_APP_CMD; do + cmd="${pair%%:*}" + have "$cmd" || printf '%s\n' "$cmd" + done +} pkgs_for_missing() { # prints the packages needed for the missing commands local pkgs="" pair cmd - for pair in $PKG_FOR_TOOL_CMD; do + for pair in $PKG_FOR_TOOL_CMD $PKG_FOR_APP_CMD; do cmd="${pair%%:*}"; pkg="${pair#*:}" have "$cmd" || pkgs="$pkgs $pkg" done @@ -374,40 +383,68 @@ pin_gpu_env() { # --- readiness check (no benchmarks run) ------------------------------------- doctor() { + local problems=() warnings=() + section "basic-benchmark doctor ($(hostname))" printf 'kit: %s\n' "$DIR" printf 'user: %s\n' "$(id -un)" printf 'TERM: %s\n' "${TERM:-}" - printf 'display: %s\n' "${WAYLAND_DISPLAY:-}${DISPLAY:-}" + printf 'display: %s\n' "${WAYLAND_DISPLAY:-}${DISPLAY:-}" if sudo -n true 2>/dev/null; then printf 'sudo: cached (ok)\n' - else printf 'sudo: will prompt - run the headless part as: ssh -t ...\n'; fi + else + printf 'sudo: will prompt for a password\n' + warnings+=("run the headless part as 'ssh -t ...' so sudo can prompt") + fi detect_dgpu printf 'dGPU: pci=%s vd=%s\n' "${GPU_PCI:-}" "${GPU_VD:-}" printf 'RAPL: %s\n' "$(ls -d /sys/class/powercap/intel-rapl:* 2>/dev/null | tr '\n' ' ')" - printf 'PassMark: %s\n' "$([ -x "$PT" ] && echo "$PT" || echo "MISSING ($PT)")" - printf 'llama: %s\n' "$([ -x "$LLAMA_BIN" ] && echo "$LLAMA_BIN" || echo "MISSING ($LLAMA_BIN)")" - printf 'model: %s\n' "$([ -f "$LLAMA_MODEL" ] && echo "$LLAMA_MODEL ($(du -h "$LLAMA_MODEL" 2>/dev/null | cut -f1))" || echo "MISSING ($LLAMA_MODEL)")" - printf 'tools:\n' - for t in 7z openssl sysbench fio stress-ng sensors turbostat cpupower \ - glmark2 vkmark glxinfo vulkaninfo nproc; do - printf ' %-22s %s\n' "$t" "$(command -v "$t" || echo MISSING)" - done - printf 'apps:\n' - for t in libreoffice inkscape gegl; do - printf ' %-22s %s\n' "$t" "$(command -v "$t" || echo MISSING)" - done - printf 'corpus: %s\n' "$CORPUS" - printf ' install apps: sudo dnf install -y libreoffice-writer libreoffice-calc inkscape gegl04-tools\n' printf 'governor: %s (pinned for timed runs; set GOVERNOR=... to choose)\n' "$GOVERNOR" - local need; need="$(pkgs_for_missing)" - if [ -z "${need// /}" ]; then - printf 'dnf: all installable tools present\n' + printf 'corpus: %s\n' "$CORPUS" + + # --- dnf-provisioned tools and apps --- + printf '\ntools (dnf-provisioned):\n' + local pair cmd pkg missing_pkgs="" + for pair in $PKG_FOR_TOOL_CMD; do + cmd="${pair%%:*}"; pkg="${pair#*:}" + if have "$cmd"; then printf ' %-14s ok\n' "$cmd" + else printf ' %-14s MISSING -> %s\n' "$cmd" "$pkg"; missing_pkgs="$missing_pkgs $pkg"; fi + done + printf 'apps (dnf-provisioned):\n' + for pair in $PKG_FOR_APP_CMD; do + cmd="${pair%%:*}"; pkg="${pair#*:}" + if have "$cmd"; then printf ' %-14s ok\n' "$cmd" + else printf ' %-14s MISSING -> %s\n' "$cmd" "$pkg"; missing_pkgs="$missing_pkgs $pkg"; fi + done + + # --- bundled binaries / data (not dnf) --- + printf 'bundled:\n' + if [ -x "$PT" ]; then printf ' %-14s ok (%s)\n' PassMark "$PT" + else printf ' %-14s MISSING -> see README section 4\n' PassMark; problems+=("PassMark binary not found at $PT"); fi + if [ -x "$LLAMA_BIN" ]; then printf ' %-14s ok\n' llama-bench + else printf ' %-14s MISSING -> see README section 4\n' llama-bench; problems+=("llama-bench not found at $LLAMA_BIN"); fi + if [ -f "$LLAMA_MODEL" ]; then printf ' %-14s ok (%s)\n' model "$(du -h "$LLAMA_MODEL" 2>/dev/null | cut -f1)" + else printf ' %-14s MISSING -> see README section 4\n' model; problems+=("GGUF model not found at $LLAMA_MODEL"); fi + if have python3 && python3 -c 'import matplotlib' >/dev/null 2>&1; then printf ' %-14s ok\n' matplotlib + else printf ' %-14s MISSING -> python3-matplotlib (graphs)\n' matplotlib; missing_pkgs="$missing_pkgs python3-matplotlib"; fi + + # --- verdict --- + if [ -z "${missing_pkgs// /}" ]; then + printf '\ndnf: nothing missing\n' else - printf 'dnf: missing:%s\n' "$need" - printf ' install with: INSTALL_DEPS=1 sudo dnf install -y%s\n' "$need" + printf '\ndnf: needed:%s\n' "$missing_pkgs" + printf ' install: sudo dnf install -y%s\n' "$missing_pkgs" + printf ' (or auto-provision: INSTALL_DEPS=1 ./run-benchmarks.sh headless)\n' fi - printf 'headless part needs: sudo (power/governor/turbostat) + a GGUF model for the LLM test.\n' - printf 'headed part needs: a graphical session + glmark2/vkmark.\n' + + if [ ${#problems[@]} -eq 0 ] && [ -z "${missing_pkgs// /}" ] && [ ${#warnings[@]} -eq 0 ]; then + printf '\nRESULT: ready - all benchmark dependencies are present.\n' + else + printf '\nRESULT: not fully ready:\n' + for p in "${problems[@]}"; do printf ' - missing dependency: %s\n' "$p"; done + [ -n "${missing_pkgs// /}" ] && printf ' - installable via dnf:%s\n' "$missing_pkgs" + for w in "${warnings[@]}"; do printf ' - %s\n' "$w"; done + fi + printf '\nnotes: headless part needs sudo (power/governor/turbostat); headed part needs a graphical session.\n' } # --- sampler + cleanup --------------------------------------------------------