From 4b2be2c990f0355772446834a05a7eb06a8f0da4 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:52:54 +0530 Subject: [PATCH 1/8] utils: lib_common.sh: add common helpers for hw-probe runner Signed-off-by: Srikanth Muppandam --- Runner/utils/lib_common.sh | 131 +++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100755 Runner/utils/lib_common.sh diff --git a/Runner/utils/lib_common.sh b/Runner/utils/lib_common.sh new file mode 100755 index 00000000..f43f82b2 --- /dev/null +++ b/Runner/utils/lib_common.sh @@ -0,0 +1,131 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# POSIX helpers that defer to functestlib.sh where available. + +# --- fallbacks only if functestlib wasn't sourced --- +if ! command -v log_info >/dev/null 2>&1; then + log_info() { printf '[INFO] %s\n' "$*"; } +fi +if ! command -v log_warn >/dev/null 2>&1; then + log_warn() { printf '[WARN] %s\n' "$*" >&2; } +fi +if ! command -v log_error >/dev/null 2>&1; then + log_error() { printf '[ERROR] %s\n' "$*" >&2; } +fi +if ! command -v log_fail >/dev/null 2>&1; then + log_fail() { printf '[FAIL] %s\n' "$*" >&2; } +fi +if ! command -v log_skip >/dev/null 2>&1; then + log_skip() { printf '[SKIP] %s\n' "$*"; } +fi + +die() { log_error "$*"; exit 1; } + +# --- cmd exists --- +have_cmd() { command -v "$1" >/dev/null 2>&1; } + +# --- root / sudo (non-interactive aware) --- +SUDO="" +is_root() { [ "$(id -u 2>/dev/null || echo 1)" -eq 0 ]; } + +# Returns: +# 0 => we can escalate non-interactively (sets $SUDO or empty when already root) +# 2 => escalation would PROMPT (caller should SKIP gracefully) +ensure_root_noprompt() { + if is_root; then + SUDO="" + return 0 + fi + + if have_cmd sudo; then + if sudo -n true >/dev/null 2>&1; then + SUDO="sudo -E" + return 0 + fi + if [ -n "${SUDO_ASKPASS:-}" ] && [ -x "${SUDO_ASKPASS:-/nonexistent}" ]; then + if sudo -A -n true >/dev/null 2>&1; then + SUDO="sudo -A -E" + return 0 + fi + fi + fi + + if have_cmd doas; then + if doas -n true >/dev/null 2>&1; then + SUDO="doas" + return 0 + fi + fi + + return 2 +} + +need_root() { + ensure_root_noprompt + rc=$? + if [ "$rc" -eq 0 ]; then + return 0 + fi + die "Root privileges required but non-interactive sudo/doas is unavailable (would prompt). Re-run as root or configure passwordless sudo." +} + +need_root_or_skip() { + ensure_root_noprompt + rc=$? + if [ "$rc" -eq 0 ]; then + return 0 + fi + log_skip "Root required but sudo/doas would prompt (no passwordless method)." + return 2 +} + +# --- ensure dir --- +ensure_dir() { + d="$1" + if [ -d "$d" ]; then + return 0 + fi + mkdir -p "$d" 2>/dev/null && return 0 + if need_root_or_skip; then + $SUDO mkdir -p "$d" || return 1 + return 0 + fi + return 1 +} + +# --- OS detect (Debian/Ubuntu) --- +detect_os_like() { + if [ -r /etc/os-release ]; then + # shellcheck source=/dev/null + . /etc/os-release + printf '%s\n' "${ID_LIKE:-$ID}" + return 0 + fi + printf '%s\n' "unknown" +} + +is_debianish() { + like="$(detect_os_like | tr '[:upper:]' '[:lower:]')" + echo "$like" | grep -Eq 'debian|ubuntu' +} + +# --- network check: prefer functestlib’s richer checks if present --- +network_is_ok() { + if command -v check_network_status >/dev/null 2>&1; then + check_network_status + return $? + fi + ping -c 1 -W 1 1.1.1.1 >/dev/null 2>&1 || ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1 +} + +ensure_network_online() { + if command -v ensure_network_online >/dev/null 2>&1; then + command ensure_network_online + return $? + fi + return 1 +} + +# --- timestamp helper --- +nowstamp() { date +%Y%m%d%H%M%S 2>/dev/null || printf '%s\n' "now"; } From 110bb40cfbea067e55455a125038f5957699e84d Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:53:05 +0530 Subject: [PATCH 2/8] utils: lib_apt.sh: apt helpers with network gating Signed-off-by: Srikanth Muppandam --- Runner/utils/lib_apt.sh | 142 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 Runner/utils/lib_apt.sh diff --git a/Runner/utils/lib_apt.sh b/Runner/utils/lib_apt.sh new file mode 100755 index 00000000..710dc28c --- /dev/null +++ b/Runner/utils/lib_apt.sh @@ -0,0 +1,142 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# APT helpers for Debian/Ubuntu. Requires lib_common.sh + functestlib logging. + +require_apt() { + have_cmd apt-get && have_cmd apt-cache && return 0 + die "apt-get/apt-cache not found. This script targets Debian/Ubuntu." +} + +apt_update_if_needed() { + require_apt + need=1 + if [ -d /var/lib/apt/lists ]; then + set -- /var/lib/apt/lists/*_Packages + if [ -e "$1" ]; then + if find /var/lib/apt/lists -name '*_Packages' -mtime -1 2>/dev/null | grep -q .; then + need=0 + fi + fi + fi + if [ "$need" -eq 1 ]; then + if ! need_root_or_skip; then + return 2 + fi + if ! network_is_ok; then + log_skip "Offline: cannot run 'apt-get update'." + return 2 + fi + log_info "cmd(root): apt-get update" + sh -c "$SUDO apt-get update" + return $? + fi + log_info "APT lists look fresh (<24h); skipping apt-get update" + return 0 +} + +apt_install_pkgs() { + require_apt + apt_update_if_needed || rc=$?; rc=${rc:-0}; [ "$rc" -eq 2 ] && return 2 + pkgs="$*" + [ -n "$pkgs" ] || return 0 + if ! need_root_or_skip; then + return 2 + fi + if ! network_is_ok; then + log_skip "Offline: cannot install $pkgs." + return 2 + fi + log_info "cmd(root): DEBIAN_FRONTEND=noninteractive apt-get install -y $pkgs" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get install -y $pkgs" + return $? +} + +apt_install_pkg_version() { + pkg="$1"; ver="$2" + if [ -z "$pkg" ] || [ -z "$ver" ]; then + die "apt_install_pkg_version: need pkg and version" + fi + require_apt + apt_update_if_needed || rc=$?; rc=${rc:-0}; [ "$rc" -eq 2 ] && return 2 + if ! need_root_or_skip; then + return 2 + fi + if ! network_is_ok; then + log_skip "Offline: cannot install ${pkg}=${ver}." + return 2 + fi + log_info "cmd(root): DEBIAN_FRONTEND=noninteractive apt-get install -y ${pkg}=${ver}" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get install -y ${pkg}=${ver}" + return $? +} + +apt_upgrade_pkg() { + pkg="$1" + if [ -z "$pkg" ]; then + die "apt_upgrade_pkg: need pkg name" + fi + require_apt + apt_update_if_needed || rc=$?; rc=${rc:-0}; [ "$rc" -eq 2 ] && return 2 + if ! need_root_or_skip; then + return 2 + fi + if ! network_is_ok; then + log_skip "Offline: cannot upgrade $pkg." + return 2 + fi + log_info "cmd(root): apt-get install -y --only-upgrade $pkg || apt-get install -y $pkg" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get install -y --only-upgrade $pkg || $SUDO DEBIAN_FRONTEND=noninteractive apt-get install -y $pkg" + return $? +} + +apt_pkg_installed() { + dpkg -s "$1" >/dev/null 2>&1 +} + +apt_list_versions() { + require_apt + pkg="$1" + log_info "Available versions for $pkg:" + if have_cmd apt-cache; then + apt-cache policy "$pkg" | sed -n 's/ *Candidate: /candidate: /p; s/ *Installed: /installed: /p; s/ *Version table://p' + apt-cache madison "$pkg" 2>/dev/null | awk '{print $1" "$2" "$3}' || true + fi +} + +apt_ensure_deps() { + deps="$*" + miss="" + for p in $deps; do + if ! apt_pkg_installed "$p"; then + miss="$miss $p" + fi + done + if [ -n "$miss" ]; then + apt_install_pkgs "$miss" + return $? + fi + log_info "All deps already installed" + return 0 +} + +# ---- New: uninstall helpers (non-interactive; no network required) ---- +apt_remove_pkgs() { + pkgs="$*" + [ -n "$pkgs" ] || return 0 + if ! need_root_or_skip; then + return 2 + fi + log_info "cmd(root): DEBIAN_FRONTEND=noninteractive apt-get purge -y $pkgs" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get purge -y $pkgs" + return $? +} + +apt_autoremove() { + if ! need_root_or_skip; then + return 2 + fi + log_info "cmd(root): DEBIAN_FRONTEND=noninteractive apt-get autoremove -y" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get autoremove -y" + return $? +} From 40567ee65abc07bb14d35d8cb1553eb68f1d0335 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:53:17 +0530 Subject: [PATCH 3/8] utils: lib_docker.sh: docker install/run helpers, sudo/group support Signed-off-by: Srikanth Muppandam --- Runner/utils/lib_docker.sh | 88 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 Runner/utils/lib_docker.sh diff --git a/Runner/utils/lib_docker.sh b/Runner/utils/lib_docker.sh new file mode 100755 index 00000000..e20b2d6c --- /dev/null +++ b/Runner/utils/lib_docker.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# Docker helpers. Requires lib_common.sh and lib_apt.sh + +docker_is_installed() { have_cmd docker; } + +docker_install() { + if docker_is_installed; then + log_info "Docker already installed" + return 0 + fi + + log_info "Installing docker.io via apt" + apt_install_pkgs docker.io || return $? + + if have_cmd systemctl; then + if ! need_root_or_skip; then + log_skip "Cannot enable docker service (root escalation would prompt)." + return 2 + fi + log_info "cmd(root): systemctl enable --now docker" + sh -c "$SUDO systemctl enable --now docker" + fi + + # Add current user to 'docker' group (best-effort), so future runs won't need sudo + if have_cmd usermod; then + if ! id -nG 2>/dev/null | grep -qw docker; then + if need_root_or_skip; then + log_info "cmd(root): usermod -aG docker $(id -un) || true" + sh -c "$SUDO usermod -aG docker $(id -un) || true" + log_info "You may need to re-login for docker group membership to apply." + else + log_skip "Cannot add user to 'docker' group (root escalation would prompt)." + fi + fi + fi + + return 0 +} + +docker_can_run() { + DCMD="$(docker_cmd)" + # shellcheck disable=SC2086 + $DCMD version >/dev/null 2>&1 +} + +docker_cmd() { + if is_root; then + printf '%s\n' "docker" + return + fi + + # If the user is in the docker group, no sudo needed + if id -nG 2>/dev/null | grep -qw docker; then + printf '%s\n' "docker" + return + fi + + # Fall back to sudo, but strictly non-interactive to avoid hangs + if have_cmd sudo && sudo -n true >/dev/null 2>&1; then + printf '%s\n' "sudo -n -E docker" + else + # Last resort: plain docker (will fail in docker_can_run if unusable) + printf '%s\n' "docker" + fi +} + +docker_image_exists() { + img="$1" + DCMD="$(docker_cmd)" + $DCMD image inspect "$img" >/dev/null 2>&1 +} + +# ---- New: uninstall docker (package) + optional disable service ---- +docker_uninstall_pkg() { + if ! docker_is_installed; then + return 0 + fi + apt_remove_pkgs docker.io || return $? + if have_cmd systemctl; then + if need_root_or_skip; then + log_info "cmd(root): systemctl disable --now docker || true" + sh -c "$SUDO systemctl disable --now docker || true" + fi + fi + return 0 +} From 01ae7c93ffdb4986e45aacb0221c07e6a135e836 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:53:28 +0530 Subject: [PATCH 4/8] utils: lib_hwprobe.sh: local & docker hw-probe orchestration, extract, URL parse Signed-off-by: Srikanth Muppandam --- Runner/utils/lib_hwprobe.sh | 347 ++++++++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100755 Runner/utils/lib_hwprobe.sh diff --git a/Runner/utils/lib_hwprobe.sh b/Runner/utils/lib_hwprobe.sh new file mode 100755 index 00000000..b2c40d42 --- /dev/null +++ b/Runner/utils/lib_hwprobe.sh @@ -0,0 +1,347 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# hw-probe helpers. Requires lib_common.sh, lib_apt.sh, lib_docker.sh + +HWPROBE_PKG="hw-probe" +HWPROBE_DEPS="lshw smartmontools nvme-cli hdparm pciutils usbutils dmidecode ethtool lsscsi iproute2" +# Flag for callers (e.g., run.sh) to know if we installed hw-probe in this run. +# shellcheck disable=SC2034 # used by run.sh; not read within this file +HWPROBE_INSTALLED_THIS_RUN=${HWPROBE_INSTALLED_THIS_RUN:-0} +export HWPROBE_INSTALLED_THIS_RUN + +hwprobe_installed() { apt_pkg_installed "$HWPROBE_PKG"; } + +# Mark if we installed hw-probe in this run (for optional uninstall) +HWPROBE_INSTALLED_THIS_RUN=0 + +hwprobe_offline_ready_local() { + if ! hwprobe_installed; then + return 1 + fi + for p in $HWPROBE_DEPS; do + if ! apt_pkg_installed "$p"; then + return 1 + fi + done + return 0 +} + +hwprobe_install_latest() { + apt_ensure_deps "$HWPROBE_DEPS" || return $? + if ! hwprobe_installed; then + apt_install_pkgs "$HWPROBE_PKG" || return $? + # shellcheck disable=SC2034 # consumed by run.sh; assignment intentional + HWPROBE_INSTALLED_THIS_RUN=1 + export HWPROBE_INSTALLED_THIS_RUN + fi + return 0 +} + +hwprobe_install_version() { + ver="$1" + apt_ensure_deps "$HWPROBE_DEPS" || return $? + if ! hwprobe_installed; then + apt_install_pkg_version "$HWPROBE_PKG" "$ver" || return $? + # shellcheck disable=SC2034 # consumed by run.sh; assignment intentional + HWPROBE_INSTALLED_THIS_RUN=1 + export HWPROBE_INSTALLED_THIS_RUN + else + apt_install_pkg_version "$HWPROBE_PKG" "$ver" || return $? + fi + return 0 +} + +hwprobe_update() { apt_upgrade_pkg "$HWPROBE_PKG"; } +hwprobe_list_versions() { apt_list_versions "$HWPROBE_PKG"; } + +hwprobe_build_local_cmd() { + upload="$1"; out="$2"; extra="$3" + cmd="hw-probe -all -save \"$out\"" + [ "$upload" = "yes" ] && cmd="$cmd -upload" + [ -n "$extra" ] && cmd="$cmd $extra" + printf '%s\n' "$cmd" +} + +_hwprobe_extract_txz() { + saved="$1"; dest="$2" + case "$saved" in + *.txz|*.tar.xz) : ;; + *) log_warn "Not a txz/tar.xz, skipping extract: $saved"; return 1 ;; + esac + [ -f "$saved" ] || { log_warn "Cannot extract: file not found: $saved"; return 1; } + ensure_dir "$dest" || { log_warn "Cannot create extract dir: $dest"; return 1; } + + if tar -tJf "$saved" >/dev/null 2>&1 && tar -xJf "$saved" -C "$dest"; then + log_info "Extracted to: $dest"; return 0 + fi + if command -v bsdtar >/dev/null 2>&1 && bsdtar -xf "$saved" -C "$dest"; then + log_info "Extracted to: $dest"; return 0 + fi + if command -v xz >/dev/null 2>&1 && xz -dc "$saved" | tar -xf - -C "$dest"; then + log_info "Extracted to: $dest"; return 0 + fi + log_warn "Failed to extract '$saved' (need tar -J, or bsdtar, or xz)." + return 1 +} + +hwprobe_run_local() { + upload="$1"; out="$2"; extra="$3"; extract="$4" + + ensure_dir "$out" || return 1 + + if ! hwprobe_installed; then + if network_is_ok; then + log_warn "hw-probe not installed; installing latest..." + hwprobe_install_latest || return $? + else + log_skip "Offline: hw-probe not installed; skipping local run." + return 2 + fi + fi + + if ! need_root_or_skip; then + return 2 + fi + + cmd="$(hwprobe_build_local_cmd "$upload" "$out" "$extra")" + log_info "cmd(root): $cmd" + tmp="${out%/}/.hw-probe-run-$(nowstamp).log" + + sh -c "$SUDO $cmd" >"$tmp" 2>&1 + rc=$? + cat "$tmp" + + url="$(sed -n 's/^.*Probe URL: *\([^ ]*linux-hardware\.org[^ ]*\).*$/\1/p' "$tmp" | tail -n 1)" + [ -n "$url" ] && log_info "Probe uploaded: $url" + + saved="$(sed -n 's/^Saved to:[[:space:]]*//p' "$tmp" | tail -n 1)" + if [ -z "$saved" ] || [ ! -f "$saved" ]; then + newest="$(find "$out" -mindepth 1 -maxdepth 1 -type f -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -n 1 | cut -d' ' -f2-)" + [ -n "$newest" ] && saved="$newest" + fi + + if [ "$rc" -eq 0 ] && [ -n "$saved" ] && [ -f "$saved" ]; then + log_info "Latest saved artifact: $saved" + log_info "List: tar -tJf \"$saved\"" + log_info "Extract: mkdir -p \"$out/extracted\" && tar -xJf \"$saved\" -C \"$out/extracted\"" + if [ "$extract" = "yes" ]; then + dest="${out%/}/extracted-$(nowstamp)" + _hwprobe_extract_txz "$saved" "$dest" || true + fi + fi + + log_info "Local report directory: $out" + return "$rc" +} + +hwprobe_run_docker() { + upload="$1"; out="$2"; extra="$3"; extract="$4" + + ensure_dir "$out" || return 1 + OUT_ABS="$(cd "$out" 2>/dev/null && pwd)" || return 1 + + # Track whether docker existed before, so the caller can optionally uninstall. + if docker_is_installed; then export __DOCKER_WAS_INSTALLED=1; else export __DOCKER_WAS_INSTALLED=0; fi + + docker_install || return $? + if ! docker_can_run; then + log_skip "Docker present but cannot run (needs group or passwordless sudo)." + return 2 + fi + + DCMD="$(docker_cmd)" + IMAGE="linuxhw/hw-probe" + CNAME="hwprobe-$(nowstamp)-$$" + + # Ensure we have the image (best-effort pull if online) + if network_is_ok; then + log_info "cmd: $DCMD pull $IMAGE || true" + $DCMD pull "$IMAGE" || true + else + if ! docker_image_exists "$IMAGE"; then + log_skip "Offline and Docker image '$IMAGE' not present locally; skipping docker run." + return 2 + fi + log_warn "Offline: skipping docker pull; using local image '$IMAGE'." + fi + + # Build a tiny script on the HOST, inside the bind mount, to avoid quoting issues. + INNER="$OUT_ABS/.inner.sh" + { + echo 'set -ex' + echo 'echo "--- container: whoami ---"; whoami || true' + echo 'echo "--- container: uname -a ---"; uname -a || true' + echo 'echo "--- container: pre-touch ---"; touch /out/__pre_touch_from_container || true' + echo 'echo "--- container: hw-probe -V ---"; hw-probe -V || true' + echo 'if [ -f /etc/alpine-release ] && command -v apk >/dev/null 2>&1; then' + echo ' apk add --no-cache kmod-libs 2>/dev/null || true' + echo 'fi' + printf 'echo "--- container: run hw-probe ---"; env DDCUTIL_DISABLE=1 hw-probe -all -save /out -log-level maximal' + [ "$upload" = "yes" ] && printf ' -upload' + [ -n "$extra" ] && printf ' %s' "$extra" + echo + echo 'echo "--- container: list /out ---"; ls -la /out || true' + echo 'echo "--- container: post-touch ---"; touch /out/__post_touch_from_container || true' + echo 'echo "--- container: done ---"' + } > "$INNER" + chmod 755 "$INNER" 2>/dev/null || true + + TS="$(nowstamp)" + DLOG="${OUT_ABS%/}/.hw-probe-docker-${TS}.log" + + # Preview exact docker run (multi-line, readable) + log_info "cmd:" + log_info " $DCMD run --name $CNAME \\" + log_info " --privileged --net=host --pid=host \\" + log_info " -v /dev:/dev \\" + log_info " -v /sys:/sys:ro \\" + log_info " -v /run/udev:/run/udev:ro \\" + log_info " -v /lib/modules:/lib/modules:ro \\" + log_info " -v /etc/os-release:/etc/os-release:ro \\" + log_info " -v /var/log:/var/log:ro \\" + log_info " -v \"$OUT_ABS\":/out \\" + log_info " --entrypoint /bin/sh \\" + log_info " \"$IMAGE\" -lc \"/out/.inner.sh 2>&1 | tee -a /out/container.log\"" + + # Run (no --rm so we can inspect/cp afterwards). Capture all stdout/stderr to DLOG. + ( + echo "== docker run start: $(date -u) ==" + $DCMD run --name "$CNAME" \ + --privileged --net=host --pid=host \ + -v /dev:/dev \ + -v /sys:/sys:ro \ + -v /run/udev:/run/udev:ro \ + -v /lib/modules:/lib/modules:ro \ + -v /etc/os-release:/etc/os-release:ro \ + -v /var/log:/var/log:ro \ + -v "$OUT_ABS":/out \ + --entrypoint /bin/sh \ + "$IMAGE" -lc "/out/.inner.sh 2>&1 | tee -a /out/container.log" + rc=$? + echo "== docker run end: $(date -u) rc=$rc ==" + exit $rc + ) >"$DLOG" 2>&1 + + run_rc=$? + + # Always show docker logs if available (helpful, but container.log is authoritative). + log_info "--- docker logs ($CNAME) ---" + $DCMD logs "$CNAME" 2>/dev/null | sed 's/^/[docker] /' || log_warn "No docker logs (possibly empty)." + + # Show container state + log_info "--- docker inspect state ($CNAME) ---" + $DCMD inspect --format='[state] Status={{.State.Status}} ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}} Error={{.State.Error}}' "$CNAME" 2>/dev/null | sed 's/^/[inspect] /' || true + + # Mirror our captured host log + the container.log written via tee inside container + if [ -s "$DLOG" ]; then + sed -e 's/^/[runner] /' "$DLOG" || true + fi + if [ -s "$OUT_ABS/container.log" ]; then + log_info "--- container.log (host copy) ---" + sed -e 's/^/[container] /' "$OUT_ABS/container.log" | tail -n 200 || true + else + log_warn "container.log not found in $OUT_ABS (script may not have run)." + fi + + # Locate artifacts on the host + saved="$(find "$OUT_ABS" -maxdepth 1 -type f -name '*.txz' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -n1 | cut -d' ' -f2-)" + pre_marker="$OUT_ABS/__pre_touch_from_container" + post_marker="$OUT_ABS/__post_touch_from_container" + + # If nothing visible on the host, try docker cp of /out + if [ -z "$saved" ] && [ ! -e "$pre_marker" ] && [ ! -e "$post_marker" ]; then + log_warn "No .txz and no markers on host. Trying docker cp fallback from container /out ..." + TMP_EXTRACT="$OUT_ABS/.from_container_$TS" + mkdir -p "$TMP_EXTRACT" 2>/dev/null || true + if $DCMD cp "$CNAME":/out/. "$TMP_EXTRACT"/ >/dev/null 2>&1; then + log_info "Copied /out from container to $TMP_EXTRACT" + find "$TMP_EXTRACT" -mindepth 1 -maxdepth 1 -printf '%p\n' 2>/dev/null | sed 's/^/[cp] /' || true + saved="$(find "$TMP_EXTRACT" -maxdepth 1 -type f -name '*.txz' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -n1 | cut -d' ' -f2-)" + [ -n "$saved" ] && { mv -f "$saved" "$OUT_ABS"/ 2>/dev/null || true; saved="$OUT_ABS/$(basename "$saved")"; } + for m in "$TMP_EXTRACT"/__pre_touch_from_container "$TMP_EXTRACT"/__post_touch_from_container; do + if [ -e "$m" ]; then + mv -f "$m" "$OUT_ABS"/ 2>/dev/null || true + fi + done + if [ -s "$TMP_EXTRACT/container.log" ]; then + cp -f "$TMP_EXTRACT/container.log" "$OUT_ABS"/ 2>/dev/null || true + fi + else + log_warn "docker cp failed or /out was empty." + fi + fi + + # Show marker status so we know if container could write to the mount + if [ -e "$pre_marker" ] || [ -e "$post_marker" ]; then + log_info "Mount sanity: pre_marker=$( [ -e "$pre_marker" ] && echo present || echo missing ), post_marker=$( [ -e "$post_marker" ] && echo present || echo missing )" + fi + + # Parse possible Probe URL (container.log usually has it) + url="" + [ -f "$OUT_ABS/container.log" ] && url="$(sed -n 's/^.*Probe URL: *\([^ ]*linux-hardware\.org[^ ]*\).*$/\1/p' "$OUT_ABS/container.log" | tail -n 1)" + [ -z "$url" ] && url="$(sed -n 's/^.*Probe URL: *\([^ ]*linux-hardware\.org[^ ]*\).*$/\1/p' "$DLOG" | tail -n 1)" + [ -n "$url" ] && log_info "Probe uploaded: $url" + + # Tidy up container (image cleanup handled elsewhere if --uninstall yes) + $DCMD rm -f "$CNAME" >/dev/null 2>&1 || true + + # Best-effort chown to current user so artifacts aren’t root-owned on host + if command -v id >/dev/null 2>&1; then + uid="$(id -u 2>/dev/null || echo)" + gid="$(id -g 2>/dev/null || echo)" + if [ -n "$uid" ] && [ -n "$gid" ]; then + if need_root_or_skip; then + log_info "Fixing ownership of $OUT_ABS -> $uid:$gid" + sh -c "$SUDO chown -R \"$uid\":\"$gid\" \"$OUT_ABS\" 2>/dev/null || true" + else + log_warn "Outputs are root-owned. re-run with sudo to chown, or copy elsewhere." + fi + fi + fi + + if [ -n "$saved" ] && [ -f "$saved" ]; then + log_info "Latest saved artifact: $saved" + log_info "List: tar -tJf \"$saved\"" + log_info "Extract: mkdir -p \"$OUT_ABS/extracted\" && tar -xJf \"$saved\" -C \"$OUT_ABS/extracted\"" + if [ "$extract" = "yes" ]; then + dest="${OUT_ABS%/}/extracted-$(nowstamp)" + _hwprobe_extract_txz "$saved" "$dest" || true + fi + log_info "Docker run complete. Report directory: $OUT_ABS" + return 0 + fi + + log_fail "No .txz artifact produced (docker run rc=$run_rc)." + log_info "Docker run complete. Report directory: $OUT_ABS" + return 1 +} + +# ---- New: uninstall hw-probe package ---- +hwprobe_uninstall_pkg() { + if ! hwprobe_installed; then + return 0 + fi + apt_remove_pkgs "$HWPROBE_PKG" || return $? + apt_autoremove || true + return 0 +} + +hwprobe_uninstall() { + if apt_pkg_installed "$HWPROBE_PKG"; then + need_root + log_info "cmd(root): apt-get remove -y $HWPROBE_PKG" + sh -c "$SUDO DEBIAN_FRONTEND=noninteractive apt-get remove -y $HWPROBE_PKG" + else + log_info "hw-probe not installed; nothing to uninstall." + fi +} + +docker_image_prune_hwprobe() { + DCMD="$(docker_cmd)" + if docker_image_exists "linuxhw/hw-probe"; then + log_info "Cleaning up Docker image linuxhw/hw-probe (best-effort)" + # shellcheck disable=SC2086 + $DCMD rmi -f linuxhw/hw-probe >/dev/null 2>&1 || true + fi +} From 42ce9af811d3102287815f90258aa291b8e90163 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:53:39 +0530 Subject: [PATCH 5/8] hw-probe: run.sh: modular CLI runner (local/docker, install/update, extract) Signed-off-by: Srikanth Muppandam --- Runner/tools/hw-probe/run.sh | 251 +++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100755 Runner/tools/hw-probe/run.sh diff --git a/Runner/tools/hw-probe/run.sh b/Runner/tools/hw-probe/run.sh new file mode 100755 index 00000000..fd7e63d3 --- /dev/null +++ b/Runner/tools/hw-probe/run.sh @@ -0,0 +1,251 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear +# hw-probe orchestrator for Debian/Ubuntu +# POSIX-only, modular, with local and Docker modes. +# Uses functestlib.sh for logging & dependency checks. + +# --------- Robustly source init_env and functestlib.sh ---------- +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" +# --- source our libs (they rely on functestlib logging) --- +# shellcheck disable=SC1091 +. "$TOOLS/lib_common.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_apt.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_docker.sh" +# shellcheck disable=SC1091 +. "$TOOLS/lib_hwprobe.sh" + +usage() { + cat < (default: no) + +Install / Update: + --install Install hw-probe (latest) if not present + --version VER Install a specific version (implies --install) + --update Update hw-probe to latest available + --deps-only Install only dependencies (no hw-probe) + +Cleanup (optional): + --uninstall yes|no After run, uninstall what we installed in this run (hw-probe and/or docker). Default: no + +Extra: + --probe-args "ARGS" Extra args passed to hw-probe (both local/docker) + --dry-run Show planned actions without executing installs/runs + --verbose Verbose logging + -h|--help Show help +EOF +} + +# Defaults +MODE="local" +UPLOAD="no" +OUT_DIR="./hw-probe_out" +EXTRACT="no" +DO_INSTALL=0 +DO_UPDATE=0 +LIST_VERS=0 +DEPS_ONLY=0 +VERSION="" +PROBE_ARGS="" +DRY=0 +VERBOSE=0 +UNINSTALL="no" + +# Parse args +while [ $# -gt 0 ]; do + case "$1" in + --mode) shift; MODE="$1" ;; + --upload) shift; UPLOAD="$1" ;; + --out) shift; OUT_DIR="$1" ;; + --extract) shift; EXTRACT="$1" ;; + --install) DO_INSTALL=1 ;; + --version) shift; VERSION="$1"; DO_INSTALL=1 ;; + --update) DO_UPDATE=1 ;; + --list-versions) LIST_VERS=1 ;; + --deps-only) DEPS_ONLY=1 ;; + --uninstall) shift; UNINSTALL="$1" ;; + --probe-args) shift; PROBE_ARGS="$1" ;; + --dry-run) DRY=1 ;; + --verbose) VERBOSE=1 ;; + -h|--help) usage; exit 0 ;; + *) log_warn "Unknown option: $1"; usage; exit 1 ;; + esac + shift +done + +# --- Verbose handling (pre-run): use maximal hw-probe logging if user didn't set it --- +if [ "$VERBOSE" = "1" ]; then + case " $PROBE_ARGS " in + *" -log-level "*|*" -minimal "*|*" -min "*|*" -maximal "*|*" -max "*) + : + ;; + *) + PROBE_ARGS="${PROBE_ARGS}${PROBE_ARGS:+ }-log-level maximal" + log_info "Verbose enabled: adding '-log-level maximal' to hw-probe" + ;; + esac +fi + +# Quick base dependencies +check_dependencies grep sed awk tee || { log_skip "Missing basic tools (grep/sed/awk/tee)"; echo "hw-probe SKIP" > ./hw-probe.res 2>/dev/null; exit 2; } +if [ "$EXTRACT" = "yes" ]; then + check_dependencies tar || { log_fail "tar is required for --extract"; echo "hw-probe FAIL" > ./hw-probe.res 2>/dev/null; exit 1; } +fi + +# Sanity: OS +if ! is_debianish; then + log_fail "This tool supports Debian/Ubuntu only." + echo "hw-probe FAIL" > ./hw-probe.res 2>/dev/null + exit 1 +fi + +# -------- Early network gate (as requested) -------- +ONLINE=0 +if network_is_ok; then ONLINE=1; fi +log_info "Network: $( [ "$ONLINE" -eq 1 ] && echo online || echo offline )" + +# Docker requires network (unless preloaded), but per patch we hard-gate to online only +if [ "$MODE" = "docker" ] && [ "$ONLINE" -ne 1 ]; then + log_skip "Docker mode requires network (to pull image unless preloaded)." + echo "hw-probe SKIP" > ./hw-probe.res + exit 2 +fi + +# Local offline allowed only if hw-probe already present +if [ "$MODE" = "local" ] && [ "$ONLINE" -ne 1 ] && ! hwprobe_installed; then + log_skip "Offline and hw-probe not installed locally; skipping." + echo "hw-probe SKIP" > ./hw-probe.res + exit 2 +fi + +# Dry-run wrapper +maybe_run() { + if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] $*" + return 0 + fi + sh -c "$*" +} + +# Actions +if [ "$LIST_VERS" -eq 1 ]; then + apt_list_versions hw-probe + if [ "$DO_INSTALL" -eq 0 ] && [ "$DO_UPDATE" -eq 0 ]; then + echo "hw-probe PASS" > ./hw-probe.res 2>/dev/null + exit 0 + fi +fi + +if [ "$DEPS_ONLY" -eq 1 ]; then + log_info "Installing dependencies only..." + if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] would install deps: $HWPROBE_DEPS" + else + apt_ensure_deps "$HWPROBE_DEPS" || true + fi + if [ "$DO_INSTALL" -eq 0 ] && [ "$DO_UPDATE" -eq 0 ] && [ "$MODE" = "local" ]; then + echo "hw-probe PASS" > ./hw-probe.res 2>/dev/null + exit 0 + fi +fi + +# Install / Update logic (local package path) +if [ "$DO_INSTALL" -eq 1 ]; then + if [ -n "$VERSION" ]; then + if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] would install hw-probe version: $VERSION" + else + hwprobe_install_version "$VERSION" || true + fi + else + if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] would install hw-probe latest" + else + hwprobe_install_latest || true + fi + fi +fi +if [ "$DO_UPDATE" -eq 1 ]; then + if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] would update hw-probe to latest" + else + hwprobe_update || true + fi +fi + +# Run +log_info "Mode=$MODE | Upload=$UPLOAD | Out=$OUT_DIR | Extract=$EXTRACT | Online=$ONLINE" + +RC=0 +if [ "$DRY" -eq 1 ]; then + log_info "[dry-run] would run hw-probe now" + RC=0 +else + case "$MODE" in + local) + hwprobe_run_local "$UPLOAD" "$OUT_DIR" "$PROBE_ARGS" "$EXTRACT" + RC=$? + ;; + docker) + hwprobe_run_docker "$UPLOAD" "$OUT_DIR" "$PROBE_ARGS" "$EXTRACT" + RC=$? + ;; + *) + log_fail "Unknown mode: $MODE" + RC=1 + ;; + esac +fi + +# ----- Post-run uninstall/cleanup as per patch ----- +if [ "$MODE" = "docker" ] && [ "$UNINSTALL" = "yes" ]; then + docker_image_prune_hwprobe || true +fi + +if [ "$UNINSTALL" = "yes" ] && [ "$MODE" = "local" ]; then + hwprobe_uninstall || true +fi + +# (Existing result handling retained) +if [ "$RC" -eq 0 ]; then + log_pass "hw-probe PASS" + echo "hw-probe PASS" > ./hw-probe.res 2>/dev/null + exit 0 +elif [ "$RC" -eq 2 ]; then + log_skip "hw-probe SKIP" + echo "hw-probe SKIP" > ./hw-probe.res 2>/dev/null + exit 2 +else + log_fail "hw-probe FAIL" + echo "hw-probe FAIL" > ./hw-probe.res 2>/dev/null + exit 1 +fi From 37b74205c398bb0dda2099f5b15434bbe8ec6f68 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 15:55:05 +0530 Subject: [PATCH 6/8] docs(hw-probe): usage, artifacts, offline & docker notes Signed-off-by: Srikanth Muppandam --- .../tools/hw-probe/README_hw-probe_runner.md | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 Runner/tools/hw-probe/README_hw-probe_runner.md diff --git a/Runner/tools/hw-probe/README_hw-probe_runner.md b/Runner/tools/hw-probe/README_hw-probe_runner.md new file mode 100644 index 00000000..dc350ae5 --- /dev/null +++ b/Runner/tools/hw-probe/README_hw-probe_runner.md @@ -0,0 +1,232 @@ +# Hardware Probe (hw-probe) Runner + +Modular, POSIX-`sh` runner to install/update and execute **[hw-probe](https://github.com/linuxhw/hw-probe)** on **Debian/Ubuntu**, with optional **Docker** mode. +Works offline (save locally) or online (upload to linux-hardware.org), and can auto-extract generated reports. + +- Uses your existing `functestlib.sh` for logging, `check_dependencies`, and `check_network_status`. +- All helpers live in `Runner/utils/` and are shared across tools. + +--- + +## Folder layout + +``` +Runner/ +├─ utils/ +│ ├─ lib_common.sh # tiny helpers (root/sudo, OS detect, ensure_dir, network check) +│ ├─ lib_apt.sh # apt install/update/version helpers +│ ├─ lib_docker.sh # docker presence/launch helpers +│ └─ lib_hwprobe.sh # hw-probe install/update/run (local & docker) + extraction +└─ tools/ + └─ hw-probe/ + ├─ run.sh # main CLI (sources init_env → functestlib → utils/*) + └─ README.md # this file +``` + +> `run.sh` auto-locates and sources your repo’s `init_env` → `${TOOLS}/functestlib.sh` so the libs can call `log_info`, `log_warn`, `log_error`, `log_fail`, `log_skip`, `check_dependencies`, `check_network_status`, etc. + +--- + +## Requirements + +- **OS:** Debian/Ubuntu (checked by the script) +- **Privileges:** root required to probe all devices + - If not root, the runner uses `sudo -E` automatically. +- **APT tools:** `apt-get`, `apt-cache`, `dpkg` +- **Network:** only needed when: + - Installing/updating packages or pulling Docker images + - Using `--upload yes` +- **Docker mode:** requires `docker` (the runner can install `docker.io` via apt) + +--- + +## What the runner does + +- Checks platform (Debian/Ubuntu) and basic tools +- Optionally installs **hw-probe** (latest or pinned version) +- Optionally updates **hw-probe** to latest +- Ensures recommended dependencies (e.g., `lshw`, `smartmontools`, `nvme-cli`, `hdparm`, `pciutils`, `usbutils`, `dmidecode`, `ethtool`, `lsscsi`, `iproute2`) +- Runs **locally** or via **Docker** +- Saves output to a specified directory (default `./hw-probe_out`) using `hw-probe -save` +- Optionally uploads probe to linux-hardware.org +- Optionally auto-extracts `hw.info.txz` to `OUT/extracted-` +- Prints: saved path, extraction hint, and (when uploaded) the Probe URL + +--- + +## Usage + +```sh +cd Runner/tools/hw-probe +./run.sh [OPTIONS] +``` + +### Options + +| Option | Values | Default | Description | +|---|---|---|---| +| `--mode` | `local` \| `docker` | `local` | Run natively or inside the official `linuxhw/hw-probe` image. | +| `--upload` | `yes` \| `no` | `no` | Upload probe to linux-hardware.org and print the URL. Auto-disabled if offline. | +| `--out` | path | `./hw-probe_out` | Directory to save artifacts (`hw.info.txz`) and logs. Created if missing. | +| `--extract` | `yes` \| `no` | `no` | Auto-extract the saved archive to `OUT/extracted-`. Requires `tar` (xz support preferred). | +| `--install` | – | – | Ensure **hw-probe** is installed (latest) if missing. | +| `--version` | string | – | Install a specific version (implies `--install`). | +| `--update` | – | – | Update **hw-probe** to the latest available version. | +| `--list-versions` | – | – | Show available versions from APT (policy/madison). | +| `--deps-only` | – | – | Install recommended dependencies only (no hw-probe). | +| `--probe-args` | quoted args | – | Extra args forwarded to `hw-probe` (both modes). | +| `--dry-run` | – | – | Print intended actions without installing/running. | +| `--verbose` | – | – | Increase logging verbosity (handled by functestlib). | +| `-h`, `--help` | – | – | Show usage. | + +> The runner uses `check_network_status` before any download (APT/Docker). If offline and `--upload yes`, it downgrades to `--upload no` for that run. + +--- + +## Quick starts + +### 1) Local run, save only (no upload), then auto-extract +```sh +./run.sh --mode local --upload no --extract yes +``` + +### 2) Local run, upload + auto-extract +```sh +./run.sh --mode local --upload yes --extract yes +``` + +### 3) Docker run, save only, custom output dir +```sh +./run.sh --mode docker --upload no --out ./out --extract yes +``` + +### 4) Install/update workflows +```sh +# Ensure deps + latest hw-probe (if missing), then run +./run.sh --install --mode local + +# Install a specific version +./run.sh --install --version 1.6 + +# Update to latest +./run.sh --update +``` + +### 5) List available package versions +```sh +./run.sh --list-versions +``` + +--- + +## Artifacts & Logs + +- **Saved report:** `OUT/hw.info.txz` (xz-compressed tar) +- **Local run log:** `OUT/.hw-probe-run-.log` +- **Docker run log:** `OUT/.hw-probe-docker-.log` +- **Auto-extraction (if `--extract yes`):** `OUT/extracted-/` + +To manually inspect or extract: + +```sh +# list +tar -tJf OUT/hw.info.txz + +# extract +mkdir -p OUT/extracted +tar -xJf OUT/hw.info.txz -C OUT/extracted + +# fallbacks if your tar lacks -J: +# bsdtar -xf OUT/hw.info.txz -C OUT/extracted +# xz -dc OUT/hw.info.txz | tar -xf - -C OUT/extracted +``` + +When `--upload yes`, the runner prints the **Probe URL** returned by hw-probe (e.g., `https://linux-hardware.org/?probe=`). + +--- + +## Docker notes + +The runner: +- Installs `docker.io` via APT if missing (Debian/Ubuntu) +- Pulls `linuxhw/hw-probe` if online; if offline it requires the image to exist locally +- Runs with: + - `--privileged --net=host --pid=host` + - Read-only binds: `/dev`, `/lib/modules`, `/etc/os-release`, `/var/log` + - Output bind: `-v "$OUT":/out` so `-save /out` persists artifacts on the host + +Your original run line is respected, and the script captures container stdout to a host log for URL parsing. + +--- + +## Extra hw-probe arguments + +Pass through to `hw-probe` via `--probe-args`, e.g.: + +```sh +# Quiet logging level (example) +./run.sh --mode local --probe-args "-log-level minimal" + +# Add ACPI table dump & decode (requires acpica-tools) +./run.sh --mode local --probe-args "-dump-acpi -decode-acpi" +``` + +--- + +## X11 warning + +If you see: +``` +WARNING: X11-related logs are not collected (try to run 'sudo -E hw-probe ...') +``` +It usually means `DISPLAY`/`XAUTHORITY` aren’t accessible to root (common on servers). To include X11 logs: + +```sh +xhost +local:root +sudo -E env DISPLAY="$DISPLAY" XAUTHORITY="$XAUTHORITY" hw-probe -all -save ./hw-probe_out +``` + +(Our runner already uses `sudo -E`; you just might need `xhost` on desktop systems.) + +--- + +## Offline use + +- Use `--upload no` (default); artifacts are saved locally. +- You can upload later when online: + ```sh + # Example: upload a saved probe + sudo -E hw-probe -upload -src /path/to/hw.info.txz + ``` + +--- + +## Security & privacy + +- `--upload yes` sends probe data to linux-hardware.org over HTTPS (see upstream privacy notes). +- Docker mode uses `--privileged` to access host hardware; run only on trusted systems. +- The runner uses `sudo -E` when needed to collect device info. + +--- + +## Exit codes + +- `0` on success +- Non-zero on failures (unsupported OS, missing critical tools, network required but offline, Docker not runnable, extraction failure ignored unless critical, etc.) + +--- + +## Troubleshooting + +- **“Unknown option: dump”** → We use `-save`, not `-dump`. If you call `hw-probe` manually, be sure to use `-save`. +- **“not in gzip format” when opening `hw.info.txz`** → It’s xz, not gzip. Use `tar -tJf` / `tar -xJf` (or `bsdtar`, or `xz -dc | tar -xf -`). +- **Offline + Docker first-time** → Ensure the image `linuxhw/hw-probe` is already present locally or run once online. +- **Network checks** → The runner calls `check_network_status` (from `functestlib.sh`) before any download; offline runs still work with `--upload no`. + +--- + +## Dev notes + +- All scripts are **POSIX `sh`**, shellcheck-friendly (only dynamic-source warnings suppressed). +- No duplicated infra—logging and basic checks come from your **`functestlib.sh`**. +- To extend behavior, prefer adding to `lib_hwprobe.sh` and surface flags via `run.sh`. From 7f2ca95b4ee2fc36f13c3c0a2c10f5ec90c799e5 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 16:02:42 +0530 Subject: [PATCH 7/8] lava: add hw-probe docker test definition - Adds Runner/tools/hw-probe/lava/hw-probe-docker.yaml - Executes hw-probe in Docker mode; script manages image pull/permissions - Publishes .res via send-to-lava.sh and parses with result_parse.sh - Stores artifacts under ./hw-probe_out with optional extract/upload Signed-off-by: Srikanth Muppandam --- Runner/plans/hw-probe_docker.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Runner/plans/hw-probe_docker.yaml diff --git a/Runner/plans/hw-probe_docker.yaml b/Runner/plans/hw-probe_docker.yaml new file mode 100644 index 00000000..0634236a --- /dev/null +++ b/Runner/plans/hw-probe_docker.yaml @@ -0,0 +1,19 @@ +metadata: + format: Lava-Test Test Definition 1.0 + name: hw-probe-docker + description: "Run hw-probe test via Docker mode" + maintainer: + - smuppand@qti.qualcomm.com + os: + - yocto open embedded + scope: + - functional + devices: + - rb + +run: + steps: + - cd Runner/tools/hw-probe + - ./run.sh --mode docker --extract yes --uninstall yes || true + - ./../../utils/send-to-lava.sh ./hw-probe.res || true + - ./../../utils/result_parse.sh || true From 8a01defb36b6c7ebedcb1ebb50175936c4c49633 Mon Sep 17 00:00:00 2001 From: Srikanth Muppandam Date: Tue, 21 Oct 2025 16:03:41 +0530 Subject: [PATCH 8/8] lava: add hw-probe local test definition - Adds Runner/tools/hw-probe/lava/hw-probe-local.yaml - Runs hw-probe locally with install/update handled by run.sh - Publishes .res via send-to-lava.sh and parses with result_parse.sh - Keeps artifacts in ./hw-probe_out and supports optional extract/upload Signed-off-by: Srikanth Muppandam --- Runner/plans/hw-probe_local.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Runner/plans/hw-probe_local.yaml diff --git a/Runner/plans/hw-probe_local.yaml b/Runner/plans/hw-probe_local.yaml new file mode 100644 index 00000000..594a04ea --- /dev/null +++ b/Runner/plans/hw-probe_local.yaml @@ -0,0 +1,19 @@ +metadata: + format: Lava-Test Test Definition 1.0 + name: hw-probe-local + description: "Run hw-probe test in local mode" + maintainer: + - smuppand@qti.qualcomm.com + os: + - yocto open embedded + scope: + - functional + devices: + - rb3gen2 + +run: + steps: + - cd Runner/tools/hw-probe + - ./run.sh --mode local --extract yes --uninstall yes || true + - ./../../utils/send-to-lava.sh ./hw-probe.res || true + - ./../../utils/result_parse.sh || true