release: bump version to 0.57.0
This commit is contained in:
373
planet.sh
373
planet.sh
@@ -120,6 +120,9 @@ FRONTEND_PID_FILE="$PLANET_STATE_DIR/frontend.pid"
|
||||
FRONTEND_LOG_FILE="$PLANET_STATE_DIR/frontend.log"
|
||||
PLANET_PORT_STATE_FILE="$PLANET_STATE_DIR/ports.env"
|
||||
FRONTEND_VITE_ENTRY="$SCRIPT_DIR/frontend/node_modules/vite/bin/vite.js"
|
||||
WINDOWS_LAN_RELAY_SCRIPT="$SCRIPT_DIR/scripts/windows-lan-relay.ps1"
|
||||
WINDOWS_FRONTEND_RELAY_PID_FILE="$PLANET_STATE_DIR/windows_frontend_relay.pid"
|
||||
WINDOWS_BACKEND_RELAY_PID_FILE="$PLANET_STATE_DIR/windows_backend_relay.pid"
|
||||
MOTION_AGENT_PID_FILE="$PLANET_STATE_DIR/motion_agent.pid"
|
||||
MOTION_AGENT_LOG_FILE="$PLANET_STATE_DIR/motion_agent.log"
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="$PLANET_CACHE_DIR/aiprovider_build.sha256"
|
||||
@@ -133,6 +136,10 @@ START_RUN_COMPLETED=0
|
||||
STARTED_BACKEND_THIS_RUN=0
|
||||
STARTED_FRONTEND_THIS_RUN=0
|
||||
STARTED_MOTION_AGENT_THIS_RUN=0
|
||||
WINDOWS_LAN_RELAY_ENABLED=0
|
||||
LAN_PUBLIC_FRONTEND_PORT="$DEFAULT_FRONTEND_PORT"
|
||||
LAN_PUBLIC_BACKEND_PORT="$DEFAULT_BACKEND_PORT"
|
||||
WINDOWS_LAN_RELAY_LISTEN_ADDRESS=""
|
||||
AI_PROVIDER_RUNTIME_ENV_NAMES=(
|
||||
SERVICE_NAME
|
||||
SERVICE_VERSION
|
||||
@@ -639,17 +646,246 @@ EOF
|
||||
log_lan_access_notes() {
|
||||
local frontend_port="$1"
|
||||
local backend_port="$2"
|
||||
local public_frontend_port="${3:-$frontend_port}"
|
||||
local public_backend_port="${4:-$backend_port}"
|
||||
local recommended_lan_ip=""
|
||||
|
||||
if recommended_lan_ip="$(get_recommended_lan_ipv4)"; then
|
||||
log_note "推荐访问地址: http://${recommended_lan_ip}:${frontend_port}"
|
||||
log_note "后端健康检查: http://${recommended_lan_ip}:${backend_port}/health"
|
||||
log_note "推荐访问地址: http://${recommended_lan_ip}:${public_frontend_port}"
|
||||
log_note "后端健康检查: http://${recommended_lan_ip}:${public_backend_port}/health"
|
||||
else
|
||||
log_note "前端已对局域网开放,请使用本机局域网 IP 访问 :${frontend_port}"
|
||||
log_note "后端已对局域网开放,请使用本机局域网 IP 访问 :${backend_port}/health"
|
||||
log_note "前端已对局域网开放,请使用本机局域网 IP 访问 :${public_frontend_port}"
|
||||
log_note "后端已对局域网开放,请使用本机局域网 IP 访问 :${public_backend_port}/health"
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_windows_lan_relays() {
|
||||
local pid_file
|
||||
local pid
|
||||
|
||||
for pid_file in "$WINDOWS_FRONTEND_RELAY_PID_FILE" "$WINDOWS_BACKEND_RELAY_PID_FILE"; do
|
||||
if [ -f "$pid_file" ]; then
|
||||
if pid="$(read_pid_file "$pid_file")"; then
|
||||
terminate_process_tree TERM "$pid"
|
||||
sleep 0.3
|
||||
terminate_process_tree KILL "$pid"
|
||||
fi
|
||||
remove_pid_file "$pid_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
start_windows_lan_relay() {
|
||||
local name="$1"
|
||||
local public_port="$2"
|
||||
local target_port="$3"
|
||||
local pid_file="$4"
|
||||
local target_host="$5"
|
||||
local listen_address="$6"
|
||||
local script_path
|
||||
local relay_pid
|
||||
|
||||
script_path="$(wslpath -w "$WINDOWS_LAN_RELAY_SCRIPT" 2>/dev/null || true)"
|
||||
if [ -z "$script_path" ]; then
|
||||
log_warn "无法转换 Windows relay 脚本路径,跳过 ${name} 局域网 relay"
|
||||
return 1
|
||||
fi
|
||||
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "$script_path" \
|
||||
-ListenAddress "$listen_address" \
|
||||
-ListenPort "$public_port" \
|
||||
-TargetHost "$target_host" \
|
||||
-TargetPort "$target_port" \
|
||||
> /dev/null 2>&1 &
|
||||
relay_pid=$!
|
||||
write_pid_file "$pid_file" "$relay_pid"
|
||||
sleep 0.5
|
||||
|
||||
if ! kill -0 "$relay_pid" 2>/dev/null; then
|
||||
remove_pid_file "$pid_file"
|
||||
log_warn "${name} Windows relay 未能监听端口 ${public_port}"
|
||||
print_windows_port_listener_details "$public_port" || true
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_success "${name} Windows relay 已启动: ${listen_address}:${public_port} -> ${target_host}:${target_port}"
|
||||
}
|
||||
|
||||
start_windows_lan_relays() {
|
||||
local target_host="127.0.0.1"
|
||||
|
||||
[ "$WINDOWS_LAN_RELAY_ENABLED" -eq 1 ] || return 0
|
||||
|
||||
cleanup_windows_lan_relays
|
||||
start_windows_lan_relay "前端" "$LAN_PUBLIC_FRONTEND_PORT" "$FRONTEND_PORT" "$WINDOWS_FRONTEND_RELAY_PID_FILE" "$target_host" "$WINDOWS_LAN_RELAY_LISTEN_ADDRESS" || return 1
|
||||
start_windows_lan_relay "后端" "$LAN_PUBLIC_BACKEND_PORT" "$BACKEND_PORT" "$WINDOWS_BACKEND_RELAY_PID_FILE" "$target_host" "$WINDOWS_LAN_RELAY_LISTEN_ADDRESS" || return 1
|
||||
}
|
||||
|
||||
run_windows_admin_powershell_script() {
|
||||
local script_path="$1"
|
||||
local warn_context="$2"
|
||||
local script_win_path=""
|
||||
|
||||
chmod 600 "$script_path" 2>/dev/null || true
|
||||
|
||||
script_win_path="$(wslpath -w "$script_path" 2>/dev/null || true)"
|
||||
if [ -z "$script_win_path" ]; then
|
||||
log_warn "${warn_context},但无法生成管理员 PowerShell 请求"
|
||||
return 1
|
||||
fi
|
||||
|
||||
powershell.exe -NoProfile -Command "Start-Process powershell.exe -Verb RunAs -Wait -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"${script_win_path}\"'" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
windows_firewall_missing_ports() {
|
||||
local frontend_port="$1"
|
||||
local backend_port="$2"
|
||||
|
||||
command -v powershell.exe >/dev/null 2>&1 || return 1
|
||||
|
||||
powershell.exe -NoProfile -Command "
|
||||
\$ErrorActionPreference = 'SilentlyContinue'
|
||||
\$ports = @([int]${frontend_port}, [int]${backend_port})
|
||||
function Test-PortAllowed {
|
||||
param([int]\$Port)
|
||||
\$displayName = 'WSL Planet ' + \$Port
|
||||
\$rule = Get-NetFirewallRule -DisplayName \$displayName -ErrorAction SilentlyContinue |
|
||||
Where-Object { \$_.Enabled -eq 'True' -and \$_.Direction -eq 'Inbound' -and \$_.Action -eq 'Allow' } |
|
||||
Select-Object -First 1
|
||||
if (-not \$rule) { return \$false }
|
||||
\$filter = \$rule | Get-NetFirewallPortFilter -ErrorAction SilentlyContinue |
|
||||
Where-Object { \$_.Protocol -in @('TCP', 'Any') -and \$_.LocalPort -eq [string]\$Port } |
|
||||
Select-Object -First 1
|
||||
if (\$filter) {
|
||||
return \$true
|
||||
}
|
||||
return \$false
|
||||
}
|
||||
\$missing = @()
|
||||
foreach (\$port in \$ports) {
|
||||
if (-not (Test-PortAllowed \$port)) { \$missing += \$port }
|
||||
}
|
||||
if (\$missing.Count -gt 0) {
|
||||
'missing=' + (\$missing -join ',')
|
||||
}
|
||||
" 2>/dev/null | tr -d '\r' | sed -nE 's/^missing=//p' | tail -n 1
|
||||
}
|
||||
|
||||
request_windows_firewall_rules_if_needed() {
|
||||
local frontend_port="$1"
|
||||
local backend_port="$2"
|
||||
local missing_ports=""
|
||||
local script_path=""
|
||||
|
||||
[ "$WINDOWS_LAN_RELAY_ENABLED" -eq 1 ] || return 0
|
||||
case "${PLANET_WINDOWS_FIREWALL_AUTO_PROMPT:-1}" in
|
||||
0|false|no|off)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
missing_ports="$(windows_firewall_missing_ports "$frontend_port" "$backend_port" || true)"
|
||||
[ -n "$missing_ports" ] || return 0
|
||||
|
||||
script_path="$PLANET_STATE_DIR/windows_firewall_planet.ps1"
|
||||
mkdir -p "$PLANET_STATE_DIR"
|
||||
cat > "$script_path" <<EOF
|
||||
\$ErrorActionPreference = 'Stop'
|
||||
\$ports = @(${missing_ports})
|
||||
foreach (\$port in \$ports) {
|
||||
\$displayName = "WSL Planet \$port"
|
||||
\$exists = Get-NetFirewallRule -DisplayName \$displayName -ErrorAction SilentlyContinue |
|
||||
Where-Object { \$_.Enabled -eq 'True' -and \$_.Direction -eq 'Inbound' -and \$_.Action -eq 'Allow' }
|
||||
if (-not \$exists) {
|
||||
New-NetFirewallRule -DisplayName \$displayName -Direction Inbound -Action Allow -Protocol TCP -LocalPort \$port | Out-Null
|
||||
}
|
||||
}
|
||||
Write-Host "Planet firewall rules are ready for ports: \$((\$ports -join ', '))"
|
||||
Start-Sleep -Seconds 2
|
||||
EOF
|
||||
|
||||
log_warn "检测到 Windows 防火墙可能未放行端口 ${missing_ports},即将请求管理员 PowerShell 添加规则"
|
||||
run_windows_admin_powershell_script "$script_path" "检测到 Windows 防火墙缺少端口 ${missing_ports} 放行规则" || {
|
||||
log_warn "管理员 PowerShell 未完成防火墙规则创建;局域网设备可能仍无法访问"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
windows_portproxy_conflict_ports() {
|
||||
local frontend_port="$1"
|
||||
local backend_port="$2"
|
||||
|
||||
command -v powershell.exe >/dev/null 2>&1 || return 1
|
||||
|
||||
powershell.exe -NoProfile -Command "
|
||||
\$ErrorActionPreference = 'SilentlyContinue'
|
||||
\$ports = @([int]${frontend_port}, [int]${backend_port})
|
||||
\$lines = @(netsh interface portproxy show v4tov4)
|
||||
\$found = @()
|
||||
foreach (\$line in \$lines) {
|
||||
if (\$line -match '^\\s*(\\S+)\\s+(\\d+)\\s+(\\S+)\\s+(\\d+)\\s*$') {
|
||||
\$listenPort = [int]\$Matches[2]
|
||||
if (\$ports -contains \$listenPort) { \$found += \$listenPort }
|
||||
}
|
||||
}
|
||||
if (\$found.Count -gt 0) {
|
||||
'conflict=' + ((\$found | Sort-Object -Unique) -join ',')
|
||||
}
|
||||
" 2>/dev/null | tr -d '\r' | sed -nE 's/^conflict=//p' | tail -n 1
|
||||
}
|
||||
|
||||
write_windows_portproxy_cleanup_script() {
|
||||
local script_path="$1"
|
||||
local frontend_port="$2"
|
||||
local backend_port="$3"
|
||||
|
||||
cat > "$script_path" <<EOF
|
||||
\$ErrorActionPreference = 'Continue'
|
||||
\$ports = @([int]${frontend_port}, [int]${backend_port})
|
||||
\$lines = @(netsh interface portproxy show v4tov4)
|
||||
\$removed = @()
|
||||
foreach (\$line in \$lines) {
|
||||
if (\$line -match '^\\s*(\\S+)\\s+(\\d+)\\s+(\\S+)\\s+(\\d+)\\s*$') {
|
||||
\$listenAddress = \$Matches[1]
|
||||
\$listenPort = [int]\$Matches[2]
|
||||
if (\$ports -contains \$listenPort) {
|
||||
netsh interface portproxy delete v4tov4 listenaddress=\$listenAddress listenport=\$listenPort | Out-Null
|
||||
\$removed += (\$listenAddress + ':' + \$listenPort)
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host "Planet removed stale portproxy rules: \$((\$removed -join ', '))"
|
||||
Start-Sleep -Seconds 2
|
||||
EOF
|
||||
}
|
||||
|
||||
request_windows_portproxy_cleanup_if_needed() {
|
||||
local frontend_port="$1"
|
||||
local backend_port="$2"
|
||||
local conflict_ports=""
|
||||
local script_path=""
|
||||
|
||||
[ "$WINDOWS_LAN_RELAY_ENABLED" -eq 1 ] || return 0
|
||||
case "${PLANET_WINDOWS_PORTPROXY_CLEANUP_PROMPT:-1}" in
|
||||
0|false|no|off)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
conflict_ports="$(windows_portproxy_conflict_ports "$frontend_port" "$backend_port" || true)"
|
||||
[ -n "$conflict_ports" ] || return 0
|
||||
|
||||
script_path="$PLANET_STATE_DIR/windows_portproxy_cleanup_planet.ps1"
|
||||
mkdir -p "$PLANET_STATE_DIR"
|
||||
write_windows_portproxy_cleanup_script "$script_path" "$frontend_port" "$backend_port"
|
||||
|
||||
log_warn "检测到旧 Windows portproxy 占用端口 ${conflict_ports},即将请求管理员 PowerShell 删除"
|
||||
run_windows_admin_powershell_script "$script_path" "检测到旧 portproxy 占用端口 ${conflict_ports}" || {
|
||||
log_warn "管理员 PowerShell 未完成旧 portproxy 清理;端口 ${conflict_ports} 可能仍被 iphlpsvc 占用"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
log_motion_agent_access_notes() {
|
||||
local motion_agent_port="$1"
|
||||
local lan_enabled="${2:-0}"
|
||||
@@ -1351,7 +1587,7 @@ fail_unreleased_port() {
|
||||
if [ -z "$(collect_port_pids "$port" || true)" ]; then
|
||||
log_error "端口 ${port} 当前环境内未发现占用进程,但端口仍不可用,请检查宿主机或外部环境占用"
|
||||
print_port_listener_details "$port"
|
||||
log_note "如果显示 Windows listener(如 svchost.exe / iphlpsvc),请优先用管理员 PowerShell 检查 portproxy:netsh interface portproxy show all;删除冲突转发或改用其他端口。"
|
||||
log_note "如果显示 Windows listener(如 svchost.exe / iphlpsvc),请优先用管理员 PowerShell 检查 portproxy:netsh interface portproxy show all;删除冲突转发后重新启动,--allow-lan 会改用临时 Windows relay。"
|
||||
else
|
||||
log_error "端口 ${port} 清理失败,请检查占用进程"
|
||||
if command -v lsof >/dev/null 2>&1; then
|
||||
@@ -1360,7 +1596,7 @@ fail_unreleased_port() {
|
||||
ss -ltnp "( sport = :${port} )" 2>/dev/null || true
|
||||
fi
|
||||
print_windows_port_listener_details "$port" || true
|
||||
log_note "请手动停止占用进程,或改用其他端口。"
|
||||
log_note "请手动停止占用进程后重试。"
|
||||
fi
|
||||
|
||||
exit 1
|
||||
@@ -1395,6 +1631,48 @@ retry_wait_for_port_release() {
|
||||
return 1
|
||||
}
|
||||
|
||||
print_windows_cleanup_recovery_steps() {
|
||||
local port="$1"
|
||||
local service_name="$2"
|
||||
local port_flag
|
||||
local command_example
|
||||
|
||||
case "$service_name" in
|
||||
前端)
|
||||
port_flag="-f"
|
||||
command_example="./planet.sh restart ${port_flag} ${port} --allow-lan"
|
||||
;;
|
||||
后端)
|
||||
port_flag="-b"
|
||||
command_example="./planet.sh restart ${port_flag} ${port} --allow-lan"
|
||||
;;
|
||||
"AI Provider")
|
||||
port_flag="-a"
|
||||
command_example="./planet.sh restart ${port_flag} ${port}"
|
||||
;;
|
||||
"Motion Agent")
|
||||
port_flag="--motion-agent-port"
|
||||
command_example="./planet.sh restart ${port_flag} ${port} --allow-lan"
|
||||
;;
|
||||
*)
|
||||
port_flag=""
|
||||
command_example="./planet.sh restart --allow-lan"
|
||||
;;
|
||||
esac
|
||||
|
||||
log_note "Windows 侧端口被 svchost.exe / iphlpsvc 占用时,通常是管理员 PowerShell 中创建过持久 portproxy 规则,例如 listenport=${port}。"
|
||||
log_note "该规则会由 Windows IP Helper 持续监听端口,项目停止后也不会自动消失;下次启动前必须先删除,否则会与 Vite/后端绑定同一端口冲突。"
|
||||
log_note "请打开“管理员 PowerShell”,优先检查并删除冲突 portproxy:"
|
||||
printf "${DIM} netsh interface portproxy show all${NC}\n"
|
||||
printf "${DIM} netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=%s${NC}\n" "$port"
|
||||
log_note "如果没有 portproxy 规则,再确认 PID/服务并临时停止对应服务:"
|
||||
printf "${DIM} netstat -ano | findstr :%s${NC}\n" "$port"
|
||||
printf "${DIM} tasklist /svc /fi \"PID eq <PID>\"${NC}\n"
|
||||
printf "${DIM} Stop-Service iphlpsvc -Force${NC}\n"
|
||||
log_note "如需局域网仍使用 ${port},请删除旧 portproxy 后重新运行 --allow-lan;脚本会使用临时 Windows relay 暴露该端口。"
|
||||
log_note "重新启动示例:${command_example}"
|
||||
}
|
||||
|
||||
force_cleanup_external_port_listener() {
|
||||
local port="$1"
|
||||
local service_name="$2"
|
||||
@@ -1487,6 +1765,7 @@ EOF
|
||||
log_warn "Windows 侧未发现端口 ${port} 监听,但端口仍不可绑定"
|
||||
elif [ "$saw_cleanup_failure" -eq 1 ]; then
|
||||
log_warn "Windows 侧监听清理失败,端口 ${port} 仍不可绑定"
|
||||
print_windows_cleanup_recovery_steps "$port" "$service_name"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
@@ -1885,6 +2164,48 @@ wait_for_port_release() {
|
||||
return 1
|
||||
}
|
||||
|
||||
get_windows_lan_ipv4() {
|
||||
command -v powershell.exe >/dev/null 2>&1 || return 1
|
||||
|
||||
powershell.exe -NoProfile -Command "
|
||||
\$ErrorActionPreference = 'SilentlyContinue'
|
||||
\$route = Get-NetRoute -DestinationPrefix '0.0.0.0/0' |
|
||||
Where-Object { \$_.NextHop -and \$_.NextHop -ne '0.0.0.0' } |
|
||||
Sort-Object RouteMetric, InterfaceMetric |
|
||||
Select-Object -First 1
|
||||
if (\$route) {
|
||||
\$ip = Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex \$route.InterfaceIndex |
|
||||
Where-Object { \$_.IPAddress -notmatch '^(127|169\\.254)\\.' } |
|
||||
Select-Object -First 1 -ExpandProperty IPAddress
|
||||
if (\$ip) { \$ip }
|
||||
}
|
||||
" 2>/dev/null | tr -d '\r' | sed -n '1p'
|
||||
}
|
||||
|
||||
prepare_windows_lan_relay_ports() {
|
||||
local listen_address=""
|
||||
|
||||
[ "$FRONTEND_LAN_ENABLED" -eq 1 ] || return 0
|
||||
is_wsl_environment || return 0
|
||||
command -v powershell.exe >/dev/null 2>&1 || return 0
|
||||
[ -f "$WINDOWS_LAN_RELAY_SCRIPT" ] || return 0
|
||||
|
||||
listen_address="$(get_windows_lan_ipv4 || true)"
|
||||
if [ -z "$listen_address" ]; then
|
||||
log_warn "未能识别 Windows 局域网 IP,跳过 Windows 局域网 relay;本机 localhost 仍可使用 ${FRONTEND_PORT}/${BACKEND_PORT}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
WINDOWS_LAN_RELAY_ENABLED=1
|
||||
LAN_PUBLIC_FRONTEND_PORT="$FRONTEND_PORT"
|
||||
LAN_PUBLIC_BACKEND_PORT="$BACKEND_PORT"
|
||||
WINDOWS_LAN_RELAY_LISTEN_ADDRESS="$listen_address"
|
||||
|
||||
cleanup_windows_lan_relays
|
||||
request_windows_portproxy_cleanup_if_needed "$LAN_PUBLIC_FRONTEND_PORT" "$LAN_PUBLIC_BACKEND_PORT" || true
|
||||
log_note "WSL 局域网 relay: Windows ${WINDOWS_LAN_RELAY_LISTEN_ADDRESS}:${LAN_PUBLIC_FRONTEND_PORT}/${LAN_PUBLIC_BACKEND_PORT} -> localhost:${FRONTEND_PORT}/${BACKEND_PORT}"
|
||||
}
|
||||
|
||||
kill_port_if_requested() {
|
||||
local port="$1"
|
||||
local service_name="$2"
|
||||
@@ -2071,6 +2392,7 @@ start_frontend_with_retry() {
|
||||
local frontend_port="$1"
|
||||
local frontend_port_requested="${2:-0}"
|
||||
local frontend_lan_enabled="${3:-0}"
|
||||
local backend_port="${4:-$DEFAULT_BACKEND_PORT}"
|
||||
local retry=1
|
||||
|
||||
while [ "$retry" -le "$FRONTEND_MAX_RETRIES" ]; do
|
||||
@@ -2087,7 +2409,7 @@ start_frontend_with_retry() {
|
||||
frontend_args+=(--host 0.0.0.0)
|
||||
fi
|
||||
frontend_args+=(--port "$frontend_port" --strictPort)
|
||||
nohup "$FRONTEND_RUNTIME_BIN" "${frontend_args[@]}" > "$FRONTEND_LOG_FILE" 2>&1 &
|
||||
PLANET_BACKEND_PORT="$backend_port" nohup "$FRONTEND_RUNTIME_BIN" "${frontend_args[@]}" > "$FRONTEND_LOG_FILE" 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
write_pid_file "$FRONTEND_PID_FILE" "$FRONTEND_PID"
|
||||
|
||||
@@ -2114,6 +2436,7 @@ start_frontend_service() {
|
||||
local frontend_port="$1"
|
||||
local frontend_port_requested="$2"
|
||||
local frontend_lan_enabled="${3:-0}"
|
||||
local backend_port="${4:-$DEFAULT_BACKEND_PORT}"
|
||||
|
||||
if [ "$frontend_port_requested" -eq 1 ]; then
|
||||
kill_port_if_requested "$frontend_port" "前端"
|
||||
@@ -2130,11 +2453,14 @@ start_frontend_service() {
|
||||
else
|
||||
set_wait_detail "启动 Vite 开发服务器"
|
||||
fi
|
||||
if ! start_frontend_with_retry "$frontend_port" "$frontend_port_requested" "$frontend_lan_enabled"; then
|
||||
if ! start_frontend_with_retry "$frontend_port" "$frontend_port_requested" "$frontend_lan_enabled" "$backend_port"; then
|
||||
stop_wait_session
|
||||
log_error "前端启动失败,已重试 ${FRONTEND_MAX_RETRIES} 次"
|
||||
tail -10 "$FRONTEND_LOG_FILE"
|
||||
print_port_listener_details "$frontend_port"
|
||||
if frontend_log_indicates_port_conflict "$FRONTEND_LOG_FILE"; then
|
||||
print_windows_cleanup_recovery_steps "$frontend_port" "前端"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
stop_wait_session
|
||||
@@ -2485,6 +2811,7 @@ cleanup_failed_start() {
|
||||
|
||||
clear_wait_spinner
|
||||
log_warn "启动未完成,清理本轮已拉起的本地进程"
|
||||
cleanup_windows_lan_relays
|
||||
|
||||
if [ "$STARTED_MOTION_AGENT_THIS_RUN" -eq 1 ]; then
|
||||
cleanup_motion_agent_processes TERM
|
||||
@@ -2605,6 +2932,7 @@ PY
|
||||
# Top-level commands
|
||||
start() {
|
||||
parse_service_args "$@"
|
||||
prepare_windows_lan_relay_ports
|
||||
cleanup_exit_containers
|
||||
|
||||
START_RUN_ACTIVE=1
|
||||
@@ -2617,7 +2945,7 @@ start() {
|
||||
|
||||
start_backend_service "$BACKEND_PORT" "$BACKEND_PORT_REQUESTED" "$AI_PROVIDER_PORT"
|
||||
STARTED_BACKEND_THIS_RUN=1
|
||||
start_frontend_service "$FRONTEND_PORT" "$FRONTEND_PORT_REQUESTED" "$FRONTEND_LAN_ENABLED"
|
||||
start_frontend_service "$FRONTEND_PORT" "$FRONTEND_PORT_REQUESTED" "$FRONTEND_LAN_ENABLED" "$BACKEND_PORT"
|
||||
STARTED_FRONTEND_THIS_RUN=1
|
||||
if [ "$MOTION_AGENT_REQUESTED" -eq 1 ]; then
|
||||
start_motion_agent_service "$MOTION_AGENT_PORT" "$MOTION_AGENT_DRY_RUN" "$FRONTEND_LAN_ENABLED"
|
||||
@@ -2625,24 +2953,37 @@ start() {
|
||||
fi
|
||||
|
||||
write_port_state "$BACKEND_PORT" "$FRONTEND_PORT" "$AI_PROVIDER_PORT" "$MOTION_AGENT_PORT"
|
||||
if [ "$WINDOWS_LAN_RELAY_ENABLED" -eq 1 ]; then
|
||||
start_windows_lan_relays
|
||||
request_windows_firewall_rules_if_needed "$LAN_PUBLIC_FRONTEND_PORT" "$LAN_PUBLIC_BACKEND_PORT" || true
|
||||
fi
|
||||
START_RUN_COMPLETED=1
|
||||
START_RUN_ACTIVE=0
|
||||
|
||||
log_success "启动完成"
|
||||
log_note "智能星球计划: http://localhost:${FRONTEND_PORT}/earth"
|
||||
log_note "智能星球仪表盘: http://localhost:${FRONTEND_PORT}/admin"
|
||||
log_note "AI Playground: http://localhost:${FRONTEND_PORT}/playground"
|
||||
log_note "智能星球开发文档: http://localhost:${BACKEND_PORT}/docs"
|
||||
if [ "$WINDOWS_LAN_RELAY_ENABLED" -eq 1 ]; then
|
||||
log_note "智能星球计划: http://localhost:${LAN_PUBLIC_FRONTEND_PORT}/earth"
|
||||
log_note "智能星球仪表盘: http://localhost:${LAN_PUBLIC_FRONTEND_PORT}/admin"
|
||||
log_note "AI Playground: http://localhost:${LAN_PUBLIC_FRONTEND_PORT}/playground"
|
||||
log_note "智能星球开发文档: http://localhost:${LAN_PUBLIC_BACKEND_PORT}/docs"
|
||||
log_note "局域网入口: http://${WINDOWS_LAN_RELAY_LISTEN_ADDRESS}:${LAN_PUBLIC_FRONTEND_PORT}/earth"
|
||||
else
|
||||
log_note "智能星球计划: http://localhost:${FRONTEND_PORT}/earth"
|
||||
log_note "智能星球仪表盘: http://localhost:${FRONTEND_PORT}/admin"
|
||||
log_note "AI Playground: http://localhost:${FRONTEND_PORT}/playground"
|
||||
log_note "智能星球开发文档: http://localhost:${BACKEND_PORT}/docs"
|
||||
fi
|
||||
if [ "$MOTION_AGENT_REQUESTED" -eq 1 ]; then
|
||||
log_motion_agent_access_notes "$MOTION_AGENT_PORT" "$FRONTEND_LAN_ENABLED"
|
||||
fi
|
||||
if [ "$FRONTEND_LAN_ENABLED" -eq 1 ]; then
|
||||
log_lan_access_notes "$FRONTEND_PORT" "$BACKEND_PORT"
|
||||
if [ "$FRONTEND_LAN_ENABLED" -eq 1 ] && [ "$WINDOWS_LAN_RELAY_ENABLED" -eq 0 ]; then
|
||||
log_lan_access_notes "$FRONTEND_PORT" "$BACKEND_PORT" "$LAN_PUBLIC_FRONTEND_PORT" "$LAN_PUBLIC_BACKEND_PORT"
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
log_warn "停止服务"
|
||||
cleanup_windows_lan_relays
|
||||
stop_backend_service
|
||||
stop_ai_provider_service
|
||||
stop_frontend_service
|
||||
@@ -2688,7 +3029,7 @@ restart() {
|
||||
if [ "$FRONTEND_PORT_REQUESTED" -eq 1 ]; then
|
||||
stop_frontend_service
|
||||
sleep 1
|
||||
start_frontend_service "$FRONTEND_PORT" 1 "$FRONTEND_LAN_ENABLED"
|
||||
start_frontend_service "$FRONTEND_PORT" 1 "$FRONTEND_LAN_ENABLED" "$BACKEND_PORT"
|
||||
fi
|
||||
|
||||
if [ "$MOTION_AGENT_REQUESTED" -eq 1 ]; then
|
||||
|
||||
Reference in New Issue
Block a user