#!/usr/bin/env bash # scripts/manual/eval_lesavka.sh - iterative health check for lesavka client/server/gadget # - Locally: probes TCP + gRPC handshake on LESAVKA_SERVER_ADDR # - Optional: if TETHYS_HOST is set, ssh to run lsusb + dmesg tail (enumeration check) # - Optional: if THEIA_HOST is set, ssh to show core/server status + hidg/uvc presence # # Env: # LESAVKA_SERVER_ADDR (default http://38.28.125.112:50051) # ITER=0 (loop forever) or number of iterations # SLEEP=10 (seconds between iterations) # TETHYS_HOST=host (ssh target for target machine; requires key auth) # THEIA_HOST=host (ssh target for server/gadget Pi) # SSH_OPTS="-o ConnectTimeout=5" (optional extra ssh flags) set -euo pipefail SERVER=${LESAVKA_SERVER_ADDR:-http://38.28.125.112:50051} # default to a few iterations instead of infinite to avoid unintentional long runs ITER=${ITER:-5} SLEEP=${SLEEP:-10} SSH_OPTS=${SSH_OPTS:-"-o ConnectTimeout=5 -o BatchMode=yes"} SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" PROTO_DIR="${PROTO_DIR:-${SCRIPT_DIR}/../../common/proto}" hostport=${SERVER#http://} hostport=${hostport#https://} host=${hostport%%:*} port=${hostport##*:} has_nc() { command -v nc >/dev/null 2>&1; } has_grpc() { command -v grpcurl >/dev/null 2>&1; } probe_server() { echo "==> [local] $(date -Is) probing $SERVER" if has_nc; then if nc -zw3 "$host" "$port"; then echo " tcp: OK (port reachable)" else echo " tcp: FAIL (port unreachable)" fi else echo " tcp: skipped (nc not present)" fi if has_grpc; then if [[ -f "${PROTO_DIR}/lesavka.proto" ]]; then if out=$(grpcurl -plaintext -max-time 5 \ -import-path "${PROTO_DIR}" -proto lesavka.proto \ "$host:$port" lesavka.Handshake/GetCapabilities 2>&1); then echo " gRPC Handshake (proto): OK → $out" else echo " gRPC Handshake (proto): FAIL → $out" fi else if out=$(grpcurl -plaintext -max-time 5 "$host:$port" list 2>&1); then echo " gRPC list (reflection): $out" else echo " gRPC list (reflection) FAIL → $out" fi fi else echo " gRPC: skipped (grpcurl not present)" fi } probe_tethys() { [[ -z "${TETHYS_HOST:-}" ]] && return echo "==> [tethys] $(date -Is) checking lsusb + dmesg tail on $TETHYS_HOST" ssh $SSH_OPTS "$TETHYS_HOST" ' lsusb; echo "--- /dev/hidraw* ---"; ls /dev/hidraw* 2>/dev/null || true; echo "--- dmesg (USB tail) ---"; dmesg | tail -n 20 ' || echo " ssh to $TETHYS_HOST failed" } probe_theia() { [[ -z "${THEIA_HOST:-}" ]] && return echo "==> [theia] $(date -Is) checking services/device nodes on $THEIA_HOST" ssh $SSH_OPTS "$THEIA_HOST" ' systemctl --no-pager --quiet is-active lesavka-core && echo "lesavka-core: active" || echo "lesavka-core: INACTIVE"; systemctl --no-pager --quiet is-active lesavka-server && echo "lesavka-server: active" || echo "lesavka-server: INACTIVE"; echo "--- hidg nodes ---"; ls -l /dev/hidg0 /dev/hidg1 2>/dev/null || true; echo "--- video nodes ---"; ls -l /dev/video* 2>/dev/null | head; echo "--- recent server log ---"; journalctl -u lesavka-server -n 20 --no-pager ' || echo " ssh to $THEIA_HOST failed" } count=0 while :; do probe_server probe_theia probe_tethys count=$((count + 1)) if [[ "$ITER" -gt 0 && "$count" -ge "$ITER" ]]; then break fi echo "==> sleeping ${SLEEP}s (iteration $count complete)" sleep "$SLEEP" done echo "Done."