From 1eea5e6bbc66ae139fb86024ee11ebbdb35fe06a Mon Sep 17 00:00:00 2001 From: Adam Shiervani Date: Mon, 11 May 2026 10:19:09 +0200 Subject: [PATCH] chore(scripts): simplify flash/build helpers and dedupe arg/device checks (#67) - flash_system.sh: rename ota_tar -> system_tar (path is staged release-artifacts//system.tar, not output/image/update_ota.tar) and only re-check device reachability after a --build, not on every invocation. - common.sh: add require_arg and prompt for SKU via normalize_system_sku so aliases live in one place; align FLASH_SKU/SYSTEM_SKU precedence between build_system.sh and flash_system.sh. - check_device.sh (new): one wrapper around check_ping/check_ssh used by both make check_device and direct CLI, removing the Makefile's hardcoded ping -c 1 / root@ duplication. - release_r2.sh, release_github.sh, run_e2e_tests.sh, build_system.sh, flash_system.sh: route all value-taking options through require_arg for consistent missing-arg errors. --- Makefile | 17 ++++---- scripts/build_system.sh | 82 +++++++++++++++++++++++++++++++----- scripts/check_device.sh | 19 +++++++++ scripts/common.sh | 87 +++++++++++++++++++++++++++++++++++++++ scripts/flash_system.sh | 67 ++++++++++++++++++++++++++---- scripts/release_github.sh | 1 + scripts/release_r2.sh | 10 ----- scripts/run_e2e_tests.sh | 15 ++++++- 8 files changed, 257 insertions(+), 41 deletions(-) create mode 100755 scripts/check_device.sh diff --git a/Makefile b/Makefile index 344b8a472..d14603d41 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # # Targets: # build - Build rv1106-system image -# flash - Flash system image to device (depends on build) +# flash - Prompt for target, build one system image, and flash it # test - Run E2E tests (depends on flash) # dev_release - Dev release (prerelease) with optional per-SKU testing # release - Production release with optional per-SKU testing @@ -12,7 +12,7 @@ VERSION := $(shell cat VERSION 2>/dev/null || echo "0.0.0") VERSION_DEV := $(VERSION)-dev$(shell date -u +%Y%m%d%H%M) -DEVICE_IP ?= 192.168.1.77 +DEVICE_IP ?= R2_PATH := r2://jetkvm-update/system SIGNING_KEY_FPR ?= OTA_ROOT_KEY_FPR := AF5A36A993D828FEFE7C18C2D1B9856C26A79E95 @@ -81,10 +81,7 @@ build: ./scripts/build_system.sh check_device: - @echo "Checking device connectivity ($(DEVICE_IP))..." - @ping -c 1 -W 5 $(DEVICE_IP) > /dev/null 2>&1 || { echo "Error: Cannot reach device at $(DEVICE_IP)"; exit 1; } - @ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@$(DEVICE_IP) "echo ok" > /dev/null 2>&1 || { echo "Error: SSH failed to root@$(DEVICE_IP)"; exit 1; } - @echo "OK: Device reachable" + @DEVICE_IP="$(DEVICE_IP)" ./scripts/check_device.sh check_remote: @echo "Checking remote host connectivity ($(JETKVM_REMOTE_HOST))..." @@ -93,11 +90,11 @@ check_remote: @echo "OK: Remote host reachable" flash: - $(MAKE) check_device ifndef SKIP_BUILD - PROMPT_VARIANT_TESTS=0 $(MAKE) build + PROMPT_VARIANT_TESTS=0 ./scripts/flash_system.sh $(if $(DEVICE_IP),-r $(DEVICE_IP)) --build $(if $(FLASH_SKU),--sku $(FLASH_SKU)) +else + ./scripts/flash_system.sh $(if $(DEVICE_IP),-r $(DEVICE_IP)) $(if $(FLASH_SKU),--sku $(FLASH_SKU)) endif - ./scripts/flash_system.sh -r $(DEVICE_IP) test: $(MAKE) check_device @@ -107,7 +104,7 @@ ifndef SKIP_BUILD else $(MAKE) flash SKIP_BUILD=1 endif - ./scripts/run_e2e_tests.sh -r $(DEVICE_IP) --remote-host $(JETKVM_REMOTE_HOST) $(if $(KVM_DIR),--kvm-dir $(KVM_DIR)) + ./scripts/run_e2e_tests.sh $(if $(DEVICE_IP),-r $(DEVICE_IP)) --remote-host $(JETKVM_REMOTE_HOST) $(if $(KVM_DIR),--kvm-dir $(KVM_DIR)) # ----------------------------------------------------------------------------- # Dev Release - Prerelease for testing diff --git a/scripts/build_system.sh b/scripts/build_system.sh index 75f20f023..b2140083b 100755 --- a/scripts/build_system.sh +++ b/scripts/build_system.sh @@ -7,6 +7,44 @@ ROOT_DIR=$(realpath "${SCRIPT_DIR}/..") source "${SCRIPT_DIR}/common.sh" +SELECTED_SKU="${FLASH_SKU:-${SYSTEM_SKU:-}}" + +show_help() { + echo "Usage: $0 [--sku ]" + echo + echo "Options:" + echo " --sku, --target, --variant " + echo " Build only one system target. Accepted values: emmc, sdmmc," + echo " ${EMMC_SKU}, ${SDMMC_SKU}." + echo " --help" + echo " Show this help message." + echo + echo "With no target, both SDMMC and EMMC release artifacts are built." +} + +while [[ $# -gt 0 ]]; do + case $1 in + --sku|--target|--variant) + require_arg "$1" "${2:-}" + SELECTED_SKU="$2" + shift 2 + ;; + --help) + show_help + exit 0 + ;; + *) + msg_err "Unknown option: $1" + show_help + exit 1 + ;; + esac +done + +if [ -n "$SELECTED_SKU" ]; then + SELECTED_SKU=$(normalize_system_sku "$SELECTED_SKU") || exit 1 +fi + if [ -z "${BUILD_VERSION:-}" ]; then base_version=$(cat "${ROOT_DIR}/VERSION" 2>/dev/null || echo "0.0.0") export BUILD_VERSION="${base_version}-dev$(date -u +%Y%m%d%H%M)" @@ -85,9 +123,6 @@ prompt_test_system_variant() { local label="$1" local sku="$2" local confirm - local device_ip="${DEVICE_IP:-192.168.1.77}" - local device_user="${DEVICE_USER:-root}" - local test_args=("-r" "$device_ip" "-u" "$device_user") if [ "${PROMPT_VARIANT_TESTS:-1}" != "1" ]; then return 0 @@ -100,13 +135,22 @@ prompt_test_system_variant() { return 0 fi + local device_ip="${DEVICE_IP:-}" + local device_user="${DEVICE_USER:-root}" + + if [ -z "$device_ip" ]; then + msg_err "Error: DEVICE_IP is required to flash and test ${label}" + msg_err "Re-run with DEVICE_IP= if needed" + exit 1 + fi + if [ -z "${JETKVM_REMOTE_HOST:-}" ]; then msg_err "Error: JETKVM_REMOTE_HOST is required to run E2E tests" msg_err "Re-run with JETKVM_REMOTE_HOST= and DEVICE_IP=${device_ip} if needed" exit 1 fi - test_args+=("--remote-host" "$JETKVM_REMOTE_HOST") + local test_args=("-r" "$device_ip" "-u" "$device_user" "--remote-host" "$JETKVM_REMOTE_HOST") if [ -n "${KVM_DIR:-}" ]; then test_args+=("--kvm-dir" "$KVM_DIR") fi @@ -115,7 +159,7 @@ prompt_test_system_variant() { fi msg_info " Flashing ${label} build to ${device_user}@${device_ip}..." - ./scripts/flash_system.sh -r "$device_ip" -u "$device_user" + ./scripts/flash_system.sh -r "$device_ip" -u "$device_user" --sku "$sku" msg_info " Running ${label} E2E tests..." ./scripts/run_e2e_tests.sh "${test_args[@]}" @@ -137,17 +181,33 @@ build_system_variant() { msg_info ">> Building rv1106-system..." cd "$ROOT_DIR" -msg_info " Cleaning previous build output..." -sudo rm -rf output/ -run_quiet "Cleaning SDK output" ./build.sh clean +clean_sdk_output() { + local message="$1" + local label="${2:-$message}" + msg_info " ${message}..." + sudo rm -rf output/ + run_quiet "$label" ./build.sh clean +} + +if [ -n "$SELECTED_SKU" ]; then + SELECTED_LABEL=$(system_variant_label "$SELECTED_SKU") || exit 1 + SELECTED_BOARD_CONFIG=$(system_variant_board_config "$SELECTED_SKU") || exit 1 + + clean_sdk_output "Cleaning SDK output" + rm -rf "$(system_variant_dir "$SELECTED_SKU")" + build_system_variant "$SELECTED_LABEL" "$SELECTED_SKU" "$SELECTED_BOARD_CONFIG" + + msg_ok "OK: Build completed" + exit 0 +fi + +clean_sdk_output "Cleaning previous build output" "Cleaning SDK output" rm -rf "$SYSTEM_RELEASE_DIR" build_system_variant "SDMMC" "$SDMMC_SKU" "$SDMMC_BOARD_CONFIG" -msg_info " Cleaning build output before EMMC..." -sudo rm -rf output/ -run_quiet "Cleaning SDK output before EMMC" ./build.sh clean +clean_sdk_output "Cleaning build output before EMMC" "Cleaning SDK output before EMMC" build_system_variant "EMMC" "$EMMC_SKU" "$EMMC_BOARD_CONFIG" diff --git a/scripts/check_device.sh b/scripts/check_device.sh new file mode 100755 index 000000000..c925cba03 --- /dev/null +++ b/scripts/check_device.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e +set -o pipefail + +SCRIPT_DIR=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")") + +source "${SCRIPT_DIR}/common.sh" + +DEVICE_IP="${DEVICE_IP:-}" +DEVICE_USER="${DEVICE_USER:-root}" + +if [ -z "$DEVICE_IP" ]; then + msg_err "Error: DEVICE_IP is required" + msg_err "Usage: DEVICE_IP= $0" + exit 1 +fi + +check_ping "$DEVICE_IP" +check_ssh "$DEVICE_USER" "$DEVICE_IP" diff --git a/scripts/common.sh b/scripts/common.sh index 421cba7e2..f9dff6853 100755 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -31,6 +31,19 @@ msg_ok() { msg "$1" "$C_OK"; } msg_err() { msg "$1" "$C_ERR"; } msg_warn() { msg "$1" "$C_WARN"; } +# ----------------------------------------------------------------------------- +# CLI argument helpers +# ----------------------------------------------------------------------------- +require_arg() { + local option="$1" + local value="${2:-}" + + if [ -z "$value" ]; then + msg_err "Error: ${option} requires a value" + exit 1 + fi +} + # ----------------------------------------------------------------------------- # SSH helper # ----------------------------------------------------------------------------- @@ -48,6 +61,10 @@ sshdev() { # ----------------------------------------------------------------------------- check_ping() { local host=$1 + if [ -z "$host" ]; then + msg_err "Error: device IP is required" + exit 1 + fi msg_info ">> Checking if device is reachable at ${host}..." if ! ping -c 3 -W 5 "${host}" > /dev/null 2>&1; then msg_err "Error: Cannot reach device at ${host}" @@ -60,6 +77,10 @@ check_ping() { check_ssh() { local user=$1 local host=$2 + if [ -z "$host" ]; then + msg_err "Error: device IP is required" + exit 1 + fi msg_info ">> Checking SSH connectivity to ${user}@${host}..." if ! ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=10 "${user}@${host}" "echo 'SSH connection successful'" > /dev/null 2>&1; then msg_err "Error: Cannot establish SSH connection to ${user}@${host}" @@ -154,6 +175,72 @@ EMMC_BOARD_CONFIG="BoardConfig_IPC/BoardConfig-EMMC-NONE-RV1106_JETKVM_V2.mk" SDMMC_SKU="jetkvm-v2-sdmmc" SDMMC_BOARD_CONFIG="BoardConfig_IPC/BoardConfig-SDMMC-NONE-RV1106_JETKVM_V2.mk" +normalize_system_sku() { + local target="$1" + case "$target" in + emmc|EMMC|jetkvm-v2) + echo "$EMMC_SKU" + ;; + sd|SD|sdmmc|SDMMC|jetkvm-v2-sdmmc) + echo "$SDMMC_SKU" + ;; + *) + msg_err "Error: unknown system target '${target}'" >&2 + msg_err "Use one of: emmc, sdmmc, ${EMMC_SKU}, ${SDMMC_SKU}" >&2 + return 1 + ;; + esac +} + +system_variant_label() { + local sku="$1" + case "$sku" in + "$EMMC_SKU") echo "EMMC" ;; + "$SDMMC_SKU") echo "SDMMC" ;; + *) + msg_err "Error: no label mapped for SKU '${sku}'" >&2 + return 1 + ;; + esac +} + +system_variant_board_config() { + local sku="$1" + case "$sku" in + "$EMMC_SKU") echo "$EMMC_BOARD_CONFIG" ;; + "$SDMMC_SKU") echo "$SDMMC_BOARD_CONFIG" ;; + *) + msg_err "Error: no board config mapped for SKU '${sku}'" >&2 + return 1 + ;; + esac +} + +prompt_system_sku() { + local choice + + if [ ! -t 0 ]; then + msg_err "Error: system target is required in non-interactive mode" >&2 + msg_err "Set FLASH_SKU or SYSTEM_SKU to emmc or sdmmc." >&2 + return 1 + fi + + { + echo "" + echo "Select system target:" + echo " 1) EMMC (${EMMC_SKU})" + echo " 2) SDMMC (${SDMMC_SKU})" + printf "Target [1/2]: " + } >&2 + read -r choice + + case "$choice" in + 1) echo "$EMMC_SKU" ;; + 2) echo "$SDMMC_SKU" ;; + *) normalize_system_sku "$choice" ;; + esac +} + system_variant_dir() { local sku="$1" echo "${SYSTEM_RELEASE_DIR}/${sku}" diff --git a/scripts/flash_system.sh b/scripts/flash_system.sh index dc6a2794c..0c4fcd827 100755 --- a/scripts/flash_system.sh +++ b/scripts/flash_system.sh @@ -5,17 +5,22 @@ set -o pipefail SCRIPT_DIR=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")") ROOT_DIR=$(realpath "${SCRIPT_DIR}/..") -DEVICE_IP="${DEVICE_IP:-192.168.1.77}" +DEVICE_IP="${DEVICE_IP:-}" DEVICE_USER="${DEVICE_USER:-root}" source "${SCRIPT_DIR}/common.sh" +BUILD_BEFORE_FLASH=false +SELECTED_SKU="${FLASH_SKU:-${SYSTEM_SKU:-}}" + show_help() { echo "Usage: $0 [options]" echo echo "Options:" - echo " -r, --remote Device IP address (default: ${DEVICE_IP})" + echo " -r, --remote Device IP address" echo " -u, --user Remote username (default: ${DEVICE_USER})" + echo " --build Build the selected target before flashing" + echo " --sku Target to flash: emmc, sdmmc, ${EMMC_SKU}, or ${SDMMC_SKU}" echo " --help Show this help message" echo } @@ -23,13 +28,24 @@ show_help() { while [[ $# -gt 0 ]]; do case $1 in -r|--remote) + require_arg "$1" "${2:-}" DEVICE_IP="$2" shift 2 ;; -u|--user) + require_arg "$1" "${2:-}" DEVICE_USER="$2" shift 2 ;; + --build) + BUILD_BEFORE_FLASH=true + shift + ;; + --sku|--target|--variant) + require_arg "$1" "${2:-}" + SELECTED_SKU="$2" + shift 2 + ;; --help) show_help exit 0 @@ -42,18 +58,53 @@ while [[ $# -gt 0 ]]; do esac done +if [ -z "$DEVICE_IP" ]; then + if [ ! -t 0 ]; then + msg_err "Error: device IP is required in non-interactive mode" + msg_err "Set DEVICE_IP= or pass -r ." + exit 1 + fi + + printf "Device IP: " >&2 + read -r DEVICE_IP + + if [ -z "$DEVICE_IP" ]; then + msg_err "Error: device IP is required" + exit 1 + fi +fi + +if [ -n "$SELECTED_SKU" ]; then + SELECTED_SKU=$(normalize_system_sku "$SELECTED_SKU") || exit 1 +else + SELECTED_SKU=$(prompt_system_sku) || exit 1 +fi + +SELECTED_LABEL=$(system_variant_label "$SELECTED_SKU") || exit 1 + check_ping "${DEVICE_IP}" check_ssh "${DEVICE_USER}" "${DEVICE_IP}" -ota_tar="$OTA_TAR" -if [ ! -f "$ota_tar" ]; then - msg_err "Error: ${ota_tar} not found. Run 'make build' first." +if [ "$BUILD_BEFORE_FLASH" = true ]; then + msg_info ">> Building ${SELECTED_LABEL} system image before flash..." + PROMPT_VARIANT_TESTS=0 "${SCRIPT_DIR}/build_system.sh" --sku "$SELECTED_SKU" + + # The build can take a while; re-confirm the device is still reachable. + msg_info ">> Re-checking device before flash..." + check_ping "${DEVICE_IP}" + check_ssh "${DEVICE_USER}" "${DEVICE_IP}" +fi + +system_tar="$(system_variant_dir "$SELECTED_SKU")/${SYSTEM_TAR_NAME}" +if [ ! -f "$system_tar" ]; then + msg_err "Error: ${system_tar} not found." + msg_err "Re-run with --build to build this target first." exit 1 fi -msg_info ">> Flashing system image to ${DEVICE_USER}@${DEVICE_IP}..." -msg_info " Transferring update_ota.tar to /userdata/jetkvm/update_system.tar..." -sshdev "cat > /userdata/jetkvm/update_system.tar" < "$ota_tar" +msg_info ">> Flashing ${SELECTED_LABEL} system image (${SELECTED_SKU}) to ${DEVICE_USER}@${DEVICE_IP}..." +msg_info " Transferring ${SYSTEM_TAR_NAME} to /userdata/jetkvm/update_system.tar..." +sshdev "cat > /userdata/jetkvm/update_system.tar" < "$system_tar" msg_ok " OK: Transfer complete" msg_info " Running rk_ota..." diff --git a/scripts/release_github.sh b/scripts/release_github.sh index 1179d2495..848ba213c 100755 --- a/scripts/release_github.sh +++ b/scripts/release_github.sh @@ -25,6 +25,7 @@ show_help() { while [[ $# -gt 0 ]]; do case $1 in --version) + require_arg "$1" "${2:-}" BUILD_VERSION="$2" shift 2 ;; diff --git a/scripts/release_r2.sh b/scripts/release_r2.sh index 8caab3d60..76444fdc0 100755 --- a/scripts/release_r2.sh +++ b/scripts/release_r2.sh @@ -53,16 +53,6 @@ validate_signing_key() { fi } -require_arg() { - local option="$1" - local value="${2:-}" - - if [ -z "$value" ]; then - msg_err "Error: ${option} requires a value" - exit 1 - fi -} - while [[ $# -gt 0 ]]; do case $1 in --version) diff --git a/scripts/run_e2e_tests.sh b/scripts/run_e2e_tests.sh index bfc0c5ee2..830a4394e 100755 --- a/scripts/run_e2e_tests.sh +++ b/scripts/run_e2e_tests.sh @@ -4,7 +4,7 @@ set -o pipefail SCRIPT_DIR=$(realpath "$(dirname "$(realpath "${BASH_SOURCE[0]}")")") -DEVICE_IP="${DEVICE_IP:-192.168.1.77}" +DEVICE_IP="${DEVICE_IP:-}" DEVICE_USER="${DEVICE_USER:-root}" KVM_REPO="${KVM_REPO:-https://github.com/jetkvm/kvm.git}" KVM_BRANCH="${KVM_BRANCH:-dev}" @@ -19,7 +19,7 @@ show_help() { echo "Usage: $0 [options]" echo echo "Options:" - echo " -r, --remote Device IP address (default: ${DEVICE_IP})" + echo " -r, --remote Device IP address" echo " -u, --user Remote username (default: ${DEVICE_USER})" echo " --kvm-dir Path to existing kvm repo (skips clone)" echo " --kvm-branch KVM branch to clone (default: ${KVM_BRANCH})" @@ -39,14 +39,17 @@ trap cleanup EXIT while [[ $# -gt 0 ]]; do case $1 in -r|--remote) + require_arg "$1" "${2:-}" DEVICE_IP="$2" shift 2 ;; -u|--user) + require_arg "$1" "${2:-}" DEVICE_USER="$2" shift 2 ;; --kvm-dir) + require_arg "$1" "${2:-}" KVM_DIR="$2" if [ ! -d "$KVM_DIR" ]; then msg_err "Error: KVM directory does not exist: $KVM_DIR" @@ -55,10 +58,12 @@ while [[ $# -gt 0 ]]; do shift 2 ;; --kvm-branch) + require_arg "$1" "${2:-}" KVM_BRANCH="$2" shift 2 ;; --remote-host) + require_arg "$1" "${2:-}" JETKVM_REMOTE_HOST="$2" shift 2 ;; @@ -80,6 +85,12 @@ if [ -z "$JETKVM_REMOTE_HOST" ]; then exit 1 fi +if [ -z "$DEVICE_IP" ]; then + msg_err "Error: device IP is required (set via -r/--remote or DEVICE_IP)" + show_help + exit 1 +fi + if [ -z "$KVM_DIR" ]; then TEMP_DIR=$(mktemp -d) KVM_DIR="$TEMP_DIR/kvm"