feat(rtty): Add remote package installation for mesh nodes
Add rttyctl commands for remote package deployment: - rttyctl install <node|all> <app_id> - Install package on node(s) - rttyctl install-status <node> [app] - Check package status - rttyctl deploy-ttyd <node|all> - Deploy ttyd web terminal RPCD methods added: - install_remote, install_mesh, deploy_ttyd, install_status Features: - Node discovery from master-link, WireGuard, P2P mesh - Auto-enables and starts ttyd after installation - Batch install with summary stats (installed/skipped/failed) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e2723946d4
commit
ac7912e0a1
@ -5232,3 +5232,15 @@ git checkout HEAD -- index.html
|
|||||||
- Fixed protocol display bug ("TCPnull" → "TCP")
|
- Fixed protocol display bug ("TCPnull" → "TCP")
|
||||||
- Removed mitmproxy-out container (not needed for WAF)
|
- Removed mitmproxy-out container (not needed for WAF)
|
||||||
- Updated MITM detection to check mitmproxy-in specifically
|
- Updated MITM detection to check mitmproxy-in specifically
|
||||||
|
|
||||||
|
### 2026-03-16
|
||||||
|
|
||||||
|
- **Remote ttyd Deployment for Mesh Nodes (Complete)**
|
||||||
|
- CLI commands: `rttyctl install <node|all> <app>`, `rttyctl install-status`, `rttyctl deploy-ttyd`
|
||||||
|
- Installs packages on remote mesh nodes via RPC proxy to AppStore
|
||||||
|
- Auto-enables and starts ttyd service after installation
|
||||||
|
- `rttyctl install all <app>` - batch install across all mesh nodes
|
||||||
|
- Node discovery from: master-link peers, WireGuard endpoints, P2P mesh
|
||||||
|
- 4 new RPCD methods: install_remote, install_mesh, deploy_ttyd, install_status
|
||||||
|
- ACL permissions updated for remote installation write actions
|
||||||
|
- Use case: Deploy ttyd web terminal to all SecuBox nodes for browser-based SSH
|
||||||
|
|||||||
@ -10,6 +10,15 @@ _Last updated: 2026-03-16 (DPI LAN Passive Analysis)_
|
|||||||
|
|
||||||
### 2026-03-16
|
### 2026-03-16
|
||||||
|
|
||||||
|
- **Remote ttyd Deployment for Mesh Nodes (Complete)**
|
||||||
|
- CLI commands: `rttyctl install`, `rttyctl install-status`, `rttyctl deploy-ttyd`
|
||||||
|
- Installs packages on remote mesh nodes via RPC proxy
|
||||||
|
- Auto-enables and starts ttyd service after installation
|
||||||
|
- `rttyctl install all <app>` - batch install across all mesh nodes
|
||||||
|
- Node discovery from: master-link, WireGuard peers, P2P mesh
|
||||||
|
- 4 new RPCD methods: install_remote, install_mesh, deploy_ttyd, install_status
|
||||||
|
- ACL permissions updated for remote installation actions
|
||||||
|
|
||||||
- **Dual-Stream DPI Phase 4 - LAN Passive Flow Analysis (Complete)**
|
- **Dual-Stream DPI Phase 4 - LAN Passive Flow Analysis (Complete)**
|
||||||
- New `dpi-lan-collector` daemon for passive br-lan monitoring
|
- New `dpi-lan-collector` daemon for passive br-lan monitoring
|
||||||
- Zero MITM, zero caching - pure nDPI/conntrack flow observation
|
- Zero MITM, zero caching - pure nDPI/conntrack flow observation
|
||||||
@ -626,8 +635,8 @@ _Last updated: 2026-03-16 (DPI LAN Passive Analysis)_
|
|||||||
|
|
||||||
### v1.0 Release Prep
|
### v1.0 Release Prep
|
||||||
|
|
||||||
1. **Remote ttyd Deployment** - Auto-install ttyd on mesh nodes
|
1. **Device Provisioning** - Use Config Vault export-clone for SecuBox replication
|
||||||
2. **Device Provisioning** - Use Config Vault export-clone for SecuBox replication
|
2. **LuCI Remote Install Button** - Add "Deploy ttyd" action to Remote Control dashboard (optional)
|
||||||
|
|
||||||
### v1.1+ Extended Mesh
|
### v1.1+ Extended Mesh
|
||||||
|
|
||||||
|
|||||||
@ -438,6 +438,126 @@ method_token_rpc() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Remote Package Installation
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Install package on remote node
|
||||||
|
method_install_remote() {
|
||||||
|
local node_id app_id
|
||||||
|
read -r input
|
||||||
|
json_load "$input"
|
||||||
|
json_get_var node_id node_id
|
||||||
|
json_get_var app_id app_id
|
||||||
|
|
||||||
|
[ -z "$node_id" ] || [ -z "$app_id" ] && {
|
||||||
|
echo '{"success":false,"error":"Missing node_id or app_id"}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute via rttyctl
|
||||||
|
local result=$($RTTYCTL install "$node_id" "$app_id" 2>&1)
|
||||||
|
local rc=$?
|
||||||
|
|
||||||
|
json_init
|
||||||
|
if [ $rc -eq 0 ] && echo "$result" | grep -q "✓"; then
|
||||||
|
json_add_boolean "success" 1
|
||||||
|
json_add_string "message" "Package $app_id installed on $node_id"
|
||||||
|
json_add_string "output" "$result"
|
||||||
|
else
|
||||||
|
json_add_boolean "success" 0
|
||||||
|
json_add_string "error" "$result"
|
||||||
|
fi
|
||||||
|
json_dump
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install package on all mesh nodes
|
||||||
|
method_install_mesh() {
|
||||||
|
local app_id
|
||||||
|
read -r input
|
||||||
|
json_load "$input"
|
||||||
|
json_get_var app_id app_id
|
||||||
|
|
||||||
|
[ -z "$app_id" ] && {
|
||||||
|
echo '{"success":false,"error":"Missing app_id"}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute via rttyctl with 'all' target
|
||||||
|
local result=$($RTTYCTL install all "$app_id" 2>&1)
|
||||||
|
local rc=$?
|
||||||
|
|
||||||
|
# Parse summary line
|
||||||
|
local installed=$(echo "$result" | grep "Summary:" | sed 's/.*: //' | cut -d, -f1 | awk '{print $1}')
|
||||||
|
local skipped=$(echo "$result" | grep "Summary:" | sed 's/.*: //' | cut -d, -f2 | awk '{print $1}')
|
||||||
|
local failed=$(echo "$result" | grep "Summary:" | sed 's/.*: //' | cut -d, -f3 | awk '{print $1}')
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_boolean "success" 1
|
||||||
|
json_add_string "app_id" "$app_id"
|
||||||
|
json_add_int "installed" "${installed:-0}"
|
||||||
|
json_add_int "skipped" "${skipped:-0}"
|
||||||
|
json_add_int "failed" "${failed:-0}"
|
||||||
|
json_add_string "output" "$result"
|
||||||
|
json_dump
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deploy ttyd to node(s) - shortcut
|
||||||
|
method_deploy_ttyd() {
|
||||||
|
local target
|
||||||
|
read -r input
|
||||||
|
json_load "$input"
|
||||||
|
json_get_var target target
|
||||||
|
|
||||||
|
[ -z "$target" ] && {
|
||||||
|
echo '{"success":false,"error":"Missing target (node_id or \"all\")"}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute via rttyctl
|
||||||
|
local result=$($RTTYCTL deploy-ttyd "$target" 2>&1)
|
||||||
|
local rc=$?
|
||||||
|
|
||||||
|
json_init
|
||||||
|
if [ $rc -eq 0 ] && echo "$result" | grep -q "✓"; then
|
||||||
|
json_add_boolean "success" 1
|
||||||
|
json_add_string "message" "ttyd deployed to $target"
|
||||||
|
|
||||||
|
# If single node, include ttyd URL
|
||||||
|
if [ "$target" != "all" ]; then
|
||||||
|
local addr=$($RTTYCTL node "$target" 2>&1 | grep "Address:" | awk '{print $2}')
|
||||||
|
[ -z "$addr" ] && addr="$target"
|
||||||
|
json_add_string "terminal_url" "http://${addr}:7681/"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
json_add_boolean "success" 0
|
||||||
|
json_add_string "error" "$result"
|
||||||
|
fi
|
||||||
|
json_dump
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check package status on remote node
|
||||||
|
method_install_status() {
|
||||||
|
local node_id app_id
|
||||||
|
read -r input
|
||||||
|
json_load "$input"
|
||||||
|
json_get_var node_id node_id
|
||||||
|
json_get_var app_id app_id
|
||||||
|
|
||||||
|
[ -z "$node_id" ] && {
|
||||||
|
echo '{"success":false,"error":"Missing node_id"}'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
local result=$($RTTYCTL install-status "$node_id" "$app_id" 2>&1)
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_boolean "success" 1
|
||||||
|
json_add_string "node_id" "$node_id"
|
||||||
|
json_add_string "output" "$result"
|
||||||
|
json_dump
|
||||||
|
}
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Avatar-Tap Session Integration
|
# Avatar-Tap Session Integration
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
@ -621,7 +741,11 @@ case "$1" in
|
|||||||
"replay_to_node": {"session_id": "integer", "target_node": "string"},
|
"replay_to_node": {"session_id": "integer", "target_node": "string"},
|
||||||
"export_session": {"session_id": "integer"},
|
"export_session": {"session_id": "integer"},
|
||||||
"import_session": {"content": "string"},
|
"import_session": {"content": "string"},
|
||||||
"get_tap_status": {}
|
"get_tap_status": {},
|
||||||
|
"install_remote": {"node_id": "string", "app_id": "string"},
|
||||||
|
"install_mesh": {"app_id": "string"},
|
||||||
|
"deploy_ttyd": {"target": "string"},
|
||||||
|
"install_status": {"node_id": "string", "app_id": "string"}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
;;
|
;;
|
||||||
@ -651,6 +775,10 @@ EOF
|
|||||||
export_session) method_export_session ;;
|
export_session) method_export_session ;;
|
||||||
import_session) method_import_session ;;
|
import_session) method_import_session ;;
|
||||||
get_tap_status) method_get_tap_status ;;
|
get_tap_status) method_get_tap_status ;;
|
||||||
|
install_remote) method_install_remote ;;
|
||||||
|
install_mesh) method_install_mesh ;;
|
||||||
|
deploy_ttyd) method_deploy_ttyd ;;
|
||||||
|
install_status) method_install_status ;;
|
||||||
*)
|
*)
|
||||||
echo '{"error":"Unknown method"}'
|
echo '{"error":"Unknown method"}'
|
||||||
;;
|
;;
|
||||||
|
|||||||
@ -14,7 +14,8 @@
|
|||||||
"token_validate",
|
"token_validate",
|
||||||
"get_tap_sessions",
|
"get_tap_sessions",
|
||||||
"get_tap_session",
|
"get_tap_session",
|
||||||
"get_tap_status"
|
"get_tap_status",
|
||||||
|
"install_status"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"uci": ["rtty-remote", "avatar-tap"]
|
"uci": ["rtty-remote", "avatar-tap"]
|
||||||
@ -34,7 +35,10 @@
|
|||||||
"token_rpc",
|
"token_rpc",
|
||||||
"replay_to_node",
|
"replay_to_node",
|
||||||
"export_session",
|
"export_session",
|
||||||
"import_session"
|
"import_session",
|
||||||
|
"install_remote",
|
||||||
|
"install_mesh",
|
||||||
|
"deploy_ttyd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"uci": ["rtty-remote"]
|
"uci": ["rtty-remote"]
|
||||||
|
|||||||
@ -936,6 +936,235 @@ cmd_tap_json_session() {
|
|||||||
"SELECT id, domain, path, method, captured_at, last_used, use_count, label FROM sessions WHERE id=$session_id" 2>/dev/null || echo '{"error":"Session not found"}'
|
"SELECT id, domain, path, method, captured_at, last_used, use_count, label FROM sessions WHERE id=$session_id" 2>/dev/null || echo '{"error":"Session not found"}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Remote Package Installation
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
cmd_install() {
|
||||||
|
local target="$1"
|
||||||
|
local app_id="$2"
|
||||||
|
|
||||||
|
[ -z "$target" ] || [ -z "$app_id" ] && {
|
||||||
|
echo "Usage: rttyctl install <node|all> <app_id>"
|
||||||
|
echo ""
|
||||||
|
echo "Install a package on remote mesh node(s)."
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " rttyctl install 192.168.255.2 ttyd"
|
||||||
|
echo " rttyctl install sb-office ttyd"
|
||||||
|
echo " rttyctl install all ttyd # Install on ALL mesh nodes"
|
||||||
|
echo ""
|
||||||
|
echo "Common apps: ttyd, crowdsec, netifyd, haproxy"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$target" = "all" ]; then
|
||||||
|
cmd_install_all "$app_id"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
local addr=$(get_node_address "$target")
|
||||||
|
[ -z "$addr" ] && die "Cannot resolve node address for: $target"
|
||||||
|
|
||||||
|
echo "Installing '$app_id' on $target ($addr)..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check if node is reachable
|
||||||
|
if ! ping -c 1 -W 2 "$addr" >/dev/null 2>&1; then
|
||||||
|
die "Node $target ($addr) is not reachable"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if already installed
|
||||||
|
echo "Checking if already installed..."
|
||||||
|
local check_result=$(cmd_rpc "$target" "luci.secubox" "check_package" "{\"package\":\"$app_id\"}" 2>/dev/null)
|
||||||
|
local installed=$(echo "$check_result" | jsonfilter -e '@.installed' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$installed" = "true" ] || [ "$installed" = "1" ]; then
|
||||||
|
echo "Package '$app_id' is already installed on $target"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install via remote RPC
|
||||||
|
echo "Installing package..."
|
||||||
|
local install_result=$(cmd_rpc "$target" "luci.secubox" "install_appstore_app" "{\"app_id\":\"$app_id\"}" 2>&1)
|
||||||
|
local rc=$?
|
||||||
|
|
||||||
|
if [ $rc -eq 0 ]; then
|
||||||
|
local success=$(echo "$install_result" | jsonfilter -e '@.success' 2>/dev/null)
|
||||||
|
if [ "$success" = "true" ] || [ "$success" = "1" ]; then
|
||||||
|
echo "✓ Successfully installed '$app_id' on $target"
|
||||||
|
log "info" "Installed $app_id on $target ($addr)"
|
||||||
|
|
||||||
|
# If ttyd, enable and start the service
|
||||||
|
if [ "$app_id" = "ttyd" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Enabling and starting ttyd service..."
|
||||||
|
cmd_rpc "$target" "luci" "setInitAction" '{"name":"ttyd","action":"enable"}' >/dev/null 2>&1
|
||||||
|
cmd_rpc "$target" "luci" "setInitAction" '{"name":"ttyd","action":"start"}' >/dev/null 2>&1
|
||||||
|
echo "✓ ttyd service enabled and started"
|
||||||
|
echo ""
|
||||||
|
echo "Web terminal available at: http://$addr:7681/"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
local error=$(echo "$install_result" | jsonfilter -e '@.error' 2>/dev/null)
|
||||||
|
echo "✗ Installation failed: ${error:-Unknown error}"
|
||||||
|
echo "Raw response: $install_result"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "✗ RPC call failed"
|
||||||
|
echo "Response: $install_result"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_install_all() {
|
||||||
|
local app_id="$1"
|
||||||
|
[ -z "$app_id" ] && die "Usage: rttyctl install all <app_id>"
|
||||||
|
|
||||||
|
echo "Installing '$app_id' on ALL mesh nodes..."
|
||||||
|
echo "========================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local success_count=0
|
||||||
|
local fail_count=0
|
||||||
|
local skip_count=0
|
||||||
|
|
||||||
|
# Get all nodes from various sources
|
||||||
|
local nodes=""
|
||||||
|
|
||||||
|
# From master-link
|
||||||
|
if command -v ml_peer_list >/dev/null 2>&1; then
|
||||||
|
local ml_nodes=$(ml_peer_list 2>/dev/null | jsonfilter -e '@.peers[*].address' 2>/dev/null)
|
||||||
|
nodes="$nodes $ml_nodes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# From WireGuard peers
|
||||||
|
if command -v wg >/dev/null 2>&1; then
|
||||||
|
local wg_nodes=$(wg show all endpoints 2>/dev/null | awk '{print $2}' | cut -d: -f1)
|
||||||
|
nodes="$nodes $wg_nodes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# From P2P mesh
|
||||||
|
if [ -x /usr/sbin/secubox-p2p ]; then
|
||||||
|
local p2p_nodes=$(/usr/sbin/secubox-p2p peers --json 2>/dev/null | jsonfilter -e '@[*].address' 2>/dev/null)
|
||||||
|
nodes="$nodes $p2p_nodes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Deduplicate and process
|
||||||
|
local unique_nodes=$(echo "$nodes" | tr ' ' '\n' | sort -u | grep -v '^$')
|
||||||
|
local total=$(echo "$unique_nodes" | wc -l)
|
||||||
|
|
||||||
|
echo "Found $total mesh nodes"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
for node in $unique_nodes; do
|
||||||
|
[ -z "$node" ] && continue
|
||||||
|
echo "[$node]"
|
||||||
|
|
||||||
|
# Skip localhost
|
||||||
|
case "$node" in
|
||||||
|
127.0.0.1|localhost|$(uci -q get network.lan.ipaddr))
|
||||||
|
echo " Skipping (local node)"
|
||||||
|
skip_count=$((skip_count + 1))
|
||||||
|
continue
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Check reachability
|
||||||
|
if ! ping -c 1 -W 2 "$node" >/dev/null 2>&1; then
|
||||||
|
echo " ✗ Not reachable"
|
||||||
|
fail_count=$((fail_count + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try to install
|
||||||
|
local result=$(cmd_rpc "$node" "luci.secubox" "install_appstore_app" "{\"app_id\":\"$app_id\"}" 2>&1)
|
||||||
|
local success=$(echo "$result" | jsonfilter -e '@.success' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$success" = "true" ] || [ "$success" = "1" ]; then
|
||||||
|
echo " ✓ Installed"
|
||||||
|
success_count=$((success_count + 1))
|
||||||
|
|
||||||
|
# Enable ttyd if that's what we installed
|
||||||
|
if [ "$app_id" = "ttyd" ]; then
|
||||||
|
cmd_rpc "$node" "luci" "setInitAction" '{"name":"ttyd","action":"enable"}' >/dev/null 2>&1
|
||||||
|
cmd_rpc "$node" "luci" "setInitAction" '{"name":"ttyd","action":"start"}' >/dev/null 2>&1
|
||||||
|
echo " ✓ ttyd enabled and started"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
local error=$(echo "$result" | jsonfilter -e '@.error' 2>/dev/null)
|
||||||
|
if echo "$error" | grep -qi "already installed"; then
|
||||||
|
echo " ⊘ Already installed"
|
||||||
|
skip_count=$((skip_count + 1))
|
||||||
|
else
|
||||||
|
echo " ✗ Failed: ${error:-Unknown error}"
|
||||||
|
fail_count=$((fail_count + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Summary: $success_count installed, $skip_count skipped, $fail_count failed"
|
||||||
|
|
||||||
|
log "info" "Mesh install of $app_id: $success_count ok, $skip_count skip, $fail_count fail"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_install_status() {
|
||||||
|
local target="$1"
|
||||||
|
local app_id="$2"
|
||||||
|
|
||||||
|
[ -z "$target" ] && {
|
||||||
|
echo "Usage: rttyctl install-status <node> [app_id]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
local addr=$(get_node_address "$target")
|
||||||
|
[ -z "$addr" ] && die "Cannot resolve node address for: $target"
|
||||||
|
|
||||||
|
echo "Package Status on $target ($addr)"
|
||||||
|
echo "=================================="
|
||||||
|
|
||||||
|
if [ -n "$app_id" ]; then
|
||||||
|
# Check specific package
|
||||||
|
local result=$(cmd_rpc "$target" "luci.secubox" "check_package" "{\"package\":\"$app_id\"}" 2>/dev/null)
|
||||||
|
local installed=$(echo "$result" | jsonfilter -e '@.installed' 2>/dev/null)
|
||||||
|
local version=$(echo "$result" | jsonfilter -e '@.version' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$installed" = "true" ] || [ "$installed" = "1" ]; then
|
||||||
|
echo " $app_id: installed (v${version:-?})"
|
||||||
|
else
|
||||||
|
echo " $app_id: not installed"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# List all SecuBox packages
|
||||||
|
local result=$(cmd_rpc "$target" "luci.secubox" "list_installed" '{}' 2>/dev/null)
|
||||||
|
echo "$result" | jsonfilter -e '@.packages[*]' 2>/dev/null | while read pkg; do
|
||||||
|
local name=$(echo "$pkg" | jsonfilter -e '@.name')
|
||||||
|
local ver=$(echo "$pkg" | jsonfilter -e '@.version')
|
||||||
|
echo " $name: $ver"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_deploy_ttyd() {
|
||||||
|
local target="$1"
|
||||||
|
|
||||||
|
[ -z "$target" ] && {
|
||||||
|
echo "Usage: rttyctl deploy-ttyd <node|all>"
|
||||||
|
echo ""
|
||||||
|
echo "Deploy ttyd web terminal to mesh node(s)."
|
||||||
|
echo "This is a shortcut for: rttyctl install <target> ttyd"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Deploying ttyd Web Terminal"
|
||||||
|
echo "==========================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
cmd_install "$target" "ttyd"
|
||||||
|
}
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Server Management
|
# Server Management
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
@ -1048,6 +1277,11 @@ RPCD Proxy:
|
|||||||
rpc-list <node> List available RPCD objects
|
rpc-list <node> List available RPCD objects
|
||||||
rpc-batch <node> <file.json> Execute batch RPCD calls
|
rpc-batch <node> <file.json> Execute batch RPCD calls
|
||||||
|
|
||||||
|
Remote Package Installation:
|
||||||
|
install <node|all> <app_id> Install package on node(s)
|
||||||
|
install-status <node> [app] Check package installation status
|
||||||
|
deploy-ttyd <node|all> Deploy ttyd web terminal (shortcut)
|
||||||
|
|
||||||
Avatar-Tap Session Replay:
|
Avatar-Tap Session Replay:
|
||||||
tap-sessions [domain] List captured sessions (filter by domain)
|
tap-sessions [domain] List captured sessions (filter by domain)
|
||||||
tap-show <id> Show session details (headers, cookies)
|
tap-show <id> Show session details (headers, cookies)
|
||||||
@ -1116,6 +1350,15 @@ case "$1" in
|
|||||||
rpc-batch)
|
rpc-batch)
|
||||||
cmd_rpc_batch "$2" "$3"
|
cmd_rpc_batch "$2" "$3"
|
||||||
;;
|
;;
|
||||||
|
install)
|
||||||
|
cmd_install "$2" "$3"
|
||||||
|
;;
|
||||||
|
install-status)
|
||||||
|
cmd_install_status "$2" "$3"
|
||||||
|
;;
|
||||||
|
deploy-ttyd)
|
||||||
|
cmd_deploy_ttyd "$2"
|
||||||
|
;;
|
||||||
sessions)
|
sessions)
|
||||||
cmd_sessions "$2"
|
cmd_sessions "$2"
|
||||||
;;
|
;;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user