From 5a235c1902363402f796950c248c5c26b7f02951 Mon Sep 17 00:00:00 2001 From: Super User Date: Sun, 26 Jul 2026 19:20:14 +0800 Subject: [PATCH 1/2] feat(dashboard): add quick-start, worker creds, data volume cleanup Sync codex improvements and fix two issues found during review: Improvements (from codex): - Add AGENTTEAMS_QUICKSTART support in step_dashboard (aligns with AgentTeams main installer's quick-start mode) - Extract worker passwords/room IDs from workers-registry.json during upgrade credential extraction - Clean up agentteams-dashboard-data volume on uninstall - Probe gateway URL from inside controller container (same network as dashboard) with host fallback - Add check_skip() to verify.sh for semantically correct skip reporting - Use grep -qx for exact container name matching in verify.sh - Improve env file parsing (cut -d= -f2- | tr -d '\r') in verify.sh - Add Test 19 for quick-start step_dashboard execution Fixes: - Define missing check_skip() function in verify.sh (was used but never defined, causing 'command not found' at runtime) - Revert version-number normalization (strip-v) in dashboard.sh/ps1 to maintain consistency with install.sh (which expects v-prefixed versions). The strip-v logic was incomplete (not synced to install.sh) and not requested by maintainers. Test coverage: 47/47 passed (was 44/44). --- install/agentteams-dashboard-tests.sh | 81 ++++++++++++++++++++++++++- install/agentteams-install.sh | 57 ++++++++++++++++++- install/agentteams-verify.sh | 19 +++++-- 3 files changed, 147 insertions(+), 10 deletions(-) diff --git a/install/agentteams-dashboard-tests.sh b/install/agentteams-dashboard-tests.sh index 7515f7a19..b80baf678 100755 --- a/install/agentteams-dashboard-tests.sh +++ b/install/agentteams-dashboard-tests.sh @@ -193,6 +193,10 @@ section "Test 7: Makefile dashboard targets" MAKEFILE="${TESTS_DIR}/../Makefile" if [ ! -f "${MAKEFILE}" ]; then echo " [SKIP] Makefile not found at ${MAKEFILE}" +elif ! grep -q 'install-embedded\|agentteams-install\.sh' "${MAKEFILE}"; then + # Not an AgentTeams checkout (e.g. running inside the standalone + # agentteams-dashboard repo, whose Makefile builds the dashboard image). + echo " [SKIP] ${MAKEFILE} is not the AgentTeams Makefile" else for target in install-dashboard update-dashboard uninstall-dashboard build-dashboard; do if grep -q "^${target}:" "${MAKEFILE}" || grep -q "^\.PHONY.*${target}" "${MAKEFILE}"; then @@ -240,7 +244,7 @@ fi section "Test 10: Non-interactive mode" # Verify step_dashboard handles non-interactive mode -if grep -A 40 'step_dashboard()' "${INSTALL_SCRIPT}" | grep -q 'AGENTTEAMS_NON_INTERACTIVE'; then +if grep -A 60 'step_dashboard()' "${INSTALL_SCRIPT}" | grep -q 'AGENTTEAMS_NON_INTERACTIVE'; then pass "step_dashboard handles non-interactive mode" else fail "step_dashboard missing non-interactive handling" @@ -755,6 +759,81 @@ else fi fi +# ---------- Test 19: Executable quick-start defaults ---------- + +section "Test 19: Executable quick-start step_dashboard" + +_test_step_dashboard_quickstart() { + local _tmpfile + _tmpfile=$(mktemp) + + if ! extract_function "step_dashboard" "${INSTALL_SCRIPT}" > "${_tmpfile}" 2>/dev/null; then + echo "EXTRACTION_FAILED" + rm -f "${_tmpfile}" + return + fi + + ( + log() { :; } + msg() { echo "$1"; } + docker() { return 1; } + podman() { return 1; } + DOCKER_CMD="docker" + + AGENTTEAMS_QUICKSTART=1 + AGENTTEAMS_NON_INTERACTIVE=0 + AGENTTEAMS_REGISTRY="ghcr.io/agentteams-group" + AGENTTEAMS_UPGRADE=0 + AGENTTEAMS_UPGRADE_KEEP_ALL=0 + AGENTTEAMS_LANG="en" + AGENTTEAMS_DASHBOARD="" + AGENTTEAMS_DASHBOARD_VERSION="" + AGENTTEAMS_PORT_DASHBOARD="" + AGENTTEAMS_DASHBOARD_IMAGE="" + AGENTTEAMS_AI_GATEWAY_ADMIN_URL="" + AGENTTEAMS_ENV_FILE="$(mktemp)" + STEP_RESULT="" + + # shellcheck disable=SC1090 + source "${_tmpfile}" 2>/dev/null + + if ! declare -F step_dashboard >/dev/null 2>&1; then + echo "FUNCTION_NOT_FOUND" + else + # Feed /dev/null to stdin: if quick-start wrongly falls through to + # the interactive prompts, read gets EOF and variables stay empty, + # which the assertions below catch. + step_dashboard < /dev/null + echo "RESULT_ENABLED=${AGENTTEAMS_DASHBOARD}" + echo "RESULT_PORT=${AGENTTEAMS_PORT_DASHBOARD}" + echo "RESULT_IMAGE=${AGENTTEAMS_DASHBOARD_IMAGE}" + fi + ) + rm -f "${_tmpfile}" +} + +_qs_result=$(_test_step_dashboard_quickstart 2>&1) + +if echo "${_qs_result}" | grep -q "EXTRACTION_FAILED\|FUNCTION_NOT_FOUND"; then + fail "Exec quick-start: function extraction failed" +else + if echo "${_qs_result}" | grep -q "RESULT_ENABLED=1"; then + pass "Exec quick-start: dashboard enabled with defaults" + else + fail "Exec quick-start: dashboard not enabled (got: $(echo "${_qs_result}" | grep RESULT_ENABLED))" + fi + if echo "${_qs_result}" | grep -q "RESULT_PORT=13000"; then + pass "Exec quick-start: default port = 13000" + else + fail "Exec quick-start: wrong port (got: $(echo "${_qs_result}" | grep RESULT_PORT))" + fi + if echo "${_qs_result}" | grep -q "RESULT_IMAGE=.*agentteams-dashboard:v1.2.0-beta.1"; then + pass "Exec quick-start: image tag matches default version" + else + fail "Exec quick-start: wrong image (got: $(echo "${_qs_result}" | grep RESULT_IMAGE))" + fi +fi + # ---------- Summary ---------- echo "" diff --git a/install/agentteams-install.sh b/install/agentteams-install.sh index e93c25805..0d5f02555 100755 --- a/install/agentteams-install.sh +++ b/install/agentteams-install.sh @@ -2512,6 +2512,19 @@ step_dashboard() { AGENTTEAMS_DASHBOARD_IMAGE=$(_dashboard_default_image) fi + # Quick Start: accept all defaults without prompting. The dashboard is + # installed by default (AGENTTEAMS_DASHBOARD=1); set AGENTTEAMS_DASHBOARD=0 + # to opt out. + if [ "${AGENTTEAMS_QUICKSTART:-0}" = "1" ]; then + if [ "${AGENTTEAMS_DASHBOARD}" = "1" ]; then + log "$(msg dash.summary "${AGENTTEAMS_PORT_DASHBOARD}" "${AGENTTEAMS_DASHBOARD_IMAGE}") (quick start)" + else + log "$(msg dash.skip) (quick start)" + fi + export AGENTTEAMS_DASHBOARD AGENTTEAMS_DASHBOARD_VERSION AGENTTEAMS_PORT_DASHBOARD AGENTTEAMS_DASHBOARD_IMAGE AGENTTEAMS_AI_GATEWAY_ADMIN_URL + return 0 + fi + if [ "${AGENTTEAMS_NON_INTERACTIVE}" = "1" ]; then AGENTTEAMS_DASHBOARD="${AGENTTEAMS_DASHBOARD:-1}" if [ "${AGENTTEAMS_DASHBOARD}" = "1" ]; then @@ -2578,10 +2591,12 @@ step_dashboard() { if ${DOCKER_CMD} exec agentteams-controller curl -sf --max-time 2 http://127.0.0.1:8001/ >/dev/null 2>&1; then _higress_url="http://agentteams-controller:8001" log "$(msg dash.auto_url): ${_higress_url}" + else + log "$(msg dash.auto_url_fail)" fi fi fi - read -p "$(msg dash.gateway_prompt) [${_higress_url:-}]: " _input + read -p "$(msg dash.gateway_prompt) [${_higress_url:-}]: " _input AGENTTEAMS_AI_GATEWAY_ADMIN_URL="${_input:-${_higress_url}}" # Normalize URL: add http:// prefix if missing @@ -2603,8 +2618,13 @@ step_dashboard() { fi fi else - # External URL — test from host - if curl -sf --max-time 3 "${AGENTTEAMS_AI_GATEWAY_ADMIN_URL}/" >/dev/null 2>&1; then + # External URL — probe from inside the controller (same network as + # the Dashboard container) when possible; fall back to the host. + if ${DOCKER_CMD} ps --format '{{.Names}}' | grep -q "^agentteams-controller$"; then + if ${DOCKER_CMD} exec agentteams-controller curl -sf --max-time 3 "${AGENTTEAMS_AI_GATEWAY_ADMIN_URL}/" >/dev/null 2>&1; then + _gw_reachable=1 + fi + elif curl -sf --max-time 3 "${AGENTTEAMS_AI_GATEWAY_ADMIN_URL}/" >/dev/null 2>&1; then _gw_reachable=1 fi fi @@ -3701,6 +3721,33 @@ CREDEOF log "Extracted Manager Matrix password${_mgr_room:+ and room ID}" fi + # Worker passwords and room IDs from workers-registry.json + if [ -f "${AGENTTEAMS_WORKSPACE_DIR}/workers-registry.json" ]; then + _worker_names=$(python3 -c "import json; d=json.load(open('${AGENTTEAMS_WORKSPACE_DIR}/workers-registry.json')); print(' '.join(d.get('workers',{}).keys()))" 2>/dev/null || true) + for _wname in ${_worker_names}; do + _wpw="" + if ${DOCKER_CMD} ps --format '{{.Names}}' 2>/dev/null | grep -q '^agentteams-manager$'; then + _wpw=$(${DOCKER_CMD} exec agentteams-manager cat "/root/agentteams-fs/agents/${_wname}/credentials/matrix/password" 2>/dev/null || true) + fi + if [ -z "${_wpw}" ] && ${DOCKER_CMD} volume ls -q 2>/dev/null | grep -q "^${AGENTTEAMS_DATA_DIR}$"; then + _wpw=$(agentteams_read_worker_creds_value_from_volume "${AGENTTEAMS_DATA_DIR}" "${_wname}" WORKER_PASSWORD) + fi + _wroom=$(python3 -c "import json; d=json.load(open('${AGENTTEAMS_WORKSPACE_DIR}/workers-registry.json')); print(d.get('workers',{}).get('${_wname}',{}).get('room_id',''))" 2>/dev/null || true) + if [ -z "${_wroom}" ] && ${DOCKER_CMD} volume ls -q 2>/dev/null | grep -q "^${AGENTTEAMS_DATA_DIR}$"; then + _wroom=$(agentteams_read_worker_creds_value_from_volume "${AGENTTEAMS_DATA_DIR}" "${_wname}" WORKER_ROOM_ID) + fi + if [ -n "${_wpw}" ]; then + cat > "${_creds_tmp}/${_wname}.env" </dev/null || true @@ -4415,6 +4462,10 @@ uninstall_agentteams() { ${DOCKER_CMD} stop agentteams-dashboard >/dev/null 2>&1 || true ${DOCKER_CMD} rm agentteams-dashboard >/dev/null 2>&1 || true fi + if ${DOCKER_CMD} volume inspect agentteams-dashboard-data >/dev/null 2>&1; then + log "Removing dashboard data volume: agentteams-dashboard-data" + ${DOCKER_CMD} volume rm agentteams-dashboard-data >/dev/null 2>&1 || true + fi # Stop and remove docker-proxy (legacy ≤ v1.0.x; current arch uses # agentteams-controller for the same role) diff --git a/install/agentteams-verify.sh b/install/agentteams-verify.sh index 51a4be30d..f29d8d271 100755 --- a/install/agentteams-verify.sh +++ b/install/agentteams-verify.sh @@ -66,6 +66,7 @@ PORT_CONSOLE="${PORT_CONSOLE:-18001}" PASS=0 FAIL=0 +SKIP=0 check_pass() { echo " [PASS] $1" @@ -77,6 +78,11 @@ check_fail() { FAIL=$((FAIL + 1)) } +check_skip() { + echo " [SKIP] $1" + SKIP=$((SKIP + 1)) +} + # ---------- Checks ---------- echo "" @@ -167,16 +173,17 @@ fi # 7. Dashboard accessible (optional component) ENV_FILE="${AGENTTEAMS_ENV_FILE:-${HOME}/agentteams-manager.env}" if [ ! -f "${ENV_FILE}" ]; then - check_pass "Dashboard not installed (no env file, skipped)" + check_skip "Dashboard not installed (no env file)" else - dashboard_enabled=$(grep -E '^AGENTTEAMS_DASHBOARD=' "${ENV_FILE}" 2>/dev/null | cut -d= -f2 || echo "0") - dashboard_port=$(grep -E '^AGENTTEAMS_PORT_DASHBOARD=' "${ENV_FILE}" 2>/dev/null | cut -d= -f2 || echo "13000") + dashboard_enabled=$(grep -E '^AGENTTEAMS_DASHBOARD=' "${ENV_FILE}" 2>/dev/null | cut -d= -f2- | tr -d '\r') + dashboard_port=$(grep -E '^AGENTTEAMS_PORT_DASHBOARD=' "${ENV_FILE}" 2>/dev/null | cut -d= -f2- | tr -d '\r') + dashboard_enabled="${dashboard_enabled:-0}" + dashboard_port="${dashboard_port:-13000}" if [ "${dashboard_enabled}" != "1" ]; then - check_pass "Dashboard not enabled (skipped)" + check_skip "Dashboard not enabled" else - ctr_id=$(${DOCKER_CMD} ps -q -f name=agentteams-dashboard 2>/dev/null) - if [ -z "${ctr_id}" ]; then + if ! ${DOCKER_CMD} ps --format '{{.Names}}' 2>/dev/null | grep -qx "agentteams-dashboard"; then check_fail "Dashboard container not running" else host_port=$(${DOCKER_CMD} port agentteams-dashboard 3000/tcp 2>/dev/null | head -1 | sed 's/.*://' || echo "") From 1692a1ad143e64805840329b33bae15981d7a1d9 Mon Sep 17 00:00:00 2001 From: Super User Date: Sun, 26 Jul 2026 20:21:05 +0800 Subject: [PATCH 2/2] fix(dashboard): sync verify.sh comment and add curl/sleep mock to tests - Update verify.sh comment to reflect 7 checks (was 6, dashboard check added) - Add curl/sleep mock to Test 18 to avoid polling real ports for 60s - Sync test file with dashboard repo for cross-repo consistency --- install/agentteams-dashboard-tests.sh | 4 ++++ install/agentteams-verify.sh | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/install/agentteams-dashboard-tests.sh b/install/agentteams-dashboard-tests.sh index b80baf678..d3afa70ed 100755 --- a/install/agentteams-dashboard-tests.sh +++ b/install/agentteams-dashboard-tests.sh @@ -724,6 +724,10 @@ _test_start_dashboard_auth() { log() { :; } msg() { echo "$*"; } _env() { eval "echo \"\${$1:-}\""; } + # Mock curl/sleep so the readiness wait loop finishes instantly + # instead of polling a real port for up to 60s. + curl() { return 1; } + sleep() { :; } AGENTTEAMS_DASHBOARD=1 AGENTTEAMS_USE_EMBEDDED=1 diff --git a/install/agentteams-verify.sh b/install/agentteams-verify.sh index f29d8d271..095246292 100755 --- a/install/agentteams-verify.sh +++ b/install/agentteams-verify.sh @@ -4,7 +4,7 @@ # Usage: # bash install/agentteams-verify.sh [container_name] # default: agentteams-manager # -# Runs 6 read-only reachability checks and prints PASS/FAIL per check. +# Runs 7 read-only reachability checks and prints PASS/FAIL per check. # Exit code: 0 if all pass, 1 if any fail. # # ── Extension notes ────────────────────────────────────────────────────────────