Merge pull request #28 from techartdev/tty-configurable-port
Add configurable terminal port support and update translations
This commit is contained in:
@@ -170,7 +170,13 @@ Control how the OpenClaw gateway binds to the network:
|
|||||||
These settings are applied automatically on add-on startup. No need to run `openclaw config` commands manually.
|
These settings are applied automatically on add-on startup. No need to run `openclaw config` commands manually.
|
||||||
|
|
||||||
### Terminal
|
### Terminal
|
||||||
- `enable_terminal` (bool, default **true**)
|
- **`enable_terminal`** (bool, default **true**)
|
||||||
|
- Enable or disable the web terminal button inside Home Assistant
|
||||||
|
|
||||||
|
- **`terminal_port`** (int, default **7681**)
|
||||||
|
- Port number for the web terminal (ttyd) to listen on
|
||||||
|
- Change this if port 7681 conflicts with another service on your system
|
||||||
|
- Valid range: 1024-65535
|
||||||
|
|
||||||
Security note: the terminal gives shell access inside the add-on container.
|
Security note: the terminal gives shell access inside the add-on container.
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ options:
|
|||||||
# Enable web terminal inside Home Assistant (Ingress) via ttyd
|
# Enable web terminal inside Home Assistant (Ingress) via ttyd
|
||||||
enable_terminal: true
|
enable_terminal: true
|
||||||
|
|
||||||
|
# Terminal port (change if 7681 conflicts with another service)
|
||||||
|
terminal_port: 7681
|
||||||
|
|
||||||
# Public base URL for opening the Gateway Web UI in a new tab (not embedded).
|
# Public base URL for opening the Gateway Web UI in a new tab (not embedded).
|
||||||
# Recommended: NO trailing slash.
|
# Recommended: NO trailing slash.
|
||||||
# Example: "https://example.duckdns.org:12345" or "http://192.168.1.10:18789"
|
# Example: "https://example.duckdns.org:12345" or "http://192.168.1.10:18789"
|
||||||
@@ -65,6 +68,7 @@ options:
|
|||||||
schema:
|
schema:
|
||||||
timezone: str
|
timezone: str
|
||||||
enable_terminal: bool?
|
enable_terminal: bool?
|
||||||
|
terminal_port: int(1024,65535)?
|
||||||
gateway_public_url: str?
|
gateway_public_url: str?
|
||||||
homeassistant_token: str?
|
homeassistant_token: str?
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ http {
|
|||||||
# Proxy everything under /terminal/ (including websocket /terminal/ws)
|
# Proxy everything under /terminal/ (including websocket /terminal/ws)
|
||||||
location ^~ /terminal/ {
|
location ^~ /terminal/ {
|
||||||
# IMPORTANT: no trailing slash in proxy_pass so nginx preserves the full URI
|
# IMPORTANT: no trailing slash in proxy_pass so nginx preserves the full URI
|
||||||
proxy_pass http://127.0.0.1:7681;
|
proxy_pass http://127.0.0.1:__TERMINAL_PORT__;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
|
|||||||
@@ -21,6 +21,19 @@ TZNAME=$(jq -r '.timezone // "Europe/Sofia"' "$OPTIONS_FILE")
|
|||||||
GW_PUBLIC_URL=$(jq -r '.gateway_public_url // empty' "$OPTIONS_FILE")
|
GW_PUBLIC_URL=$(jq -r '.gateway_public_url // empty' "$OPTIONS_FILE")
|
||||||
HA_TOKEN=$(jq -r '.homeassistant_token // empty' "$OPTIONS_FILE")
|
HA_TOKEN=$(jq -r '.homeassistant_token // empty' "$OPTIONS_FILE")
|
||||||
ENABLE_TERMINAL=$(jq -r '.enable_terminal // true' "$OPTIONS_FILE")
|
ENABLE_TERMINAL=$(jq -r '.enable_terminal // true' "$OPTIONS_FILE")
|
||||||
|
TERMINAL_PORT_RAW=$(jq -r '.terminal_port // 7681' "$OPTIONS_FILE")
|
||||||
|
|
||||||
|
# SECURITY: Validate TERMINAL_PORT to prevent nginx config injection
|
||||||
|
# Only allow numeric values in valid port range (1024-65535)
|
||||||
|
if [[ "$TERMINAL_PORT_RAW" =~ ^[0-9]+$ ]] && [ "$TERMINAL_PORT_RAW" -ge 1024 ] && [ "$TERMINAL_PORT_RAW" -le 65535 ]; then
|
||||||
|
TERMINAL_PORT="$TERMINAL_PORT_RAW"
|
||||||
|
else
|
||||||
|
echo "ERROR: Invalid terminal_port '$TERMINAL_PORT_RAW'. Must be numeric 1024-65535. Using default 7681."
|
||||||
|
TERMINAL_PORT="7681"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "DEBUG: enable_terminal config value: '$ENABLE_TERMINAL'"
|
||||||
|
echo "DEBUG: terminal_port config value: '$TERMINAL_PORT' (validated)"
|
||||||
|
|
||||||
# Generic router SSH settings
|
# Generic router SSH settings
|
||||||
ROUTER_HOST=$(jq -r '.router_ssh_host // empty' "$OPTIONS_FILE")
|
ROUTER_HOST=$(jq -r '.router_ssh_host // empty' "$OPTIONS_FILE")
|
||||||
@@ -239,12 +252,29 @@ openclaw gateway run &
|
|||||||
GW_PID=$!
|
GW_PID=$!
|
||||||
|
|
||||||
# Start web terminal (optional)
|
# Start web terminal (optional)
|
||||||
if [ "$ENABLE_TERMINAL" = "true" ]; then
|
TTYD_PID_FILE="/var/run/openclaw-ttyd.pid"
|
||||||
echo "Starting web terminal (ttyd) on 127.0.0.1:7681 ..."
|
|
||||||
ttyd -W -i 127.0.0.1 -p 7681 -b /terminal bash &
|
# Clean up stale ttyd process from previous run using PID file
|
||||||
|
if [ -f "$TTYD_PID_FILE" ]; then
|
||||||
|
OLD_PID=$(cat "$TTYD_PID_FILE" 2>/dev/null || echo "")
|
||||||
|
if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
|
||||||
|
echo "Stopping previous ttyd process (PID $OLD_PID)..."
|
||||||
|
kill "$OLD_PID" 2>/dev/null || true
|
||||||
|
sleep 1
|
||||||
|
# Force kill if still running
|
||||||
|
kill -9 "$OLD_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
rm -f "$TTYD_PID_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then
|
||||||
|
echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..."
|
||||||
|
ttyd -W -i 127.0.0.1 -p "${TERMINAL_PORT}" -b /terminal bash &
|
||||||
TTYD_PID=$!
|
TTYD_PID=$!
|
||||||
|
echo "$TTYD_PID" > "$TTYD_PID_FILE"
|
||||||
|
echo "ttyd started with PID $TTYD_PID"
|
||||||
else
|
else
|
||||||
echo "Terminal disabled (enable_terminal=false)"
|
echo "Terminal disabled (enable_terminal=$ENABLE_TERMINAL)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start ingress reverse proxy (nginx). This provides the add-on UI inside HA.
|
# Start ingress reverse proxy (nginx). This provides the add-on UI inside HA.
|
||||||
@@ -254,20 +284,22 @@ fi
|
|||||||
# The gateway token is NOT managed by the add-on; OpenClaw will generate/store it.
|
# The gateway token is NOT managed by the add-on; OpenClaw will generate/store it.
|
||||||
# Best-effort: query it via CLI (works even if openclaw.json is JSON5). If unknown, we hide the button.
|
# Best-effort: query it via CLI (works even if openclaw.json is JSON5). If unknown, we hide the button.
|
||||||
GW_TOKEN="$(timeout 2s openclaw config get gateway.auth.token 2>/dev/null | tr -d '\n' || true)"
|
GW_TOKEN="$(timeout 2s openclaw config get gateway.auth.token 2>/dev/null | tr -d '\n' || true)"
|
||||||
GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" python3 - <<'PY'
|
GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" TERMINAL_PORT="$TERMINAL_PORT" python3 - <<'PY'
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
tpl = Path('/etc/nginx/nginx.conf.tpl').read_text()
|
tpl = Path('/etc/nginx/nginx.conf.tpl').read_text()
|
||||||
landing_tpl = Path('/etc/nginx/landing.html.tpl').read_text()
|
landing_tpl = Path('/etc/nginx/landing.html.tpl').read_text()
|
||||||
public_url = os.environ.get('GW_PUBLIC_URL','')
|
public_url = os.environ.get('GW_PUBLIC_URL','')
|
||||||
|
terminal_port = os.environ.get('TERMINAL_PORT', '7681')
|
||||||
|
|
||||||
# Token comes from environment (best-effort CLI query in run.sh)
|
# Token comes from environment (best-effort CLI query in run.sh)
|
||||||
token = os.environ.get('GW_TOKEN','')
|
token = os.environ.get('GW_TOKEN','')
|
||||||
|
|
||||||
gw_path = '' if public_url.endswith('/') else '/'
|
gw_path = '' if public_url.endswith('/') else '/'
|
||||||
|
|
||||||
conf = tpl
|
# Replace terminal port placeholder in nginx config
|
||||||
|
conf = tpl.replace('__TERMINAL_PORT__', terminal_port)
|
||||||
Path('/etc/nginx/nginx.conf').write_text(conf)
|
Path('/etc/nginx/nginx.conf').write_text(conf)
|
||||||
|
|
||||||
landing = landing_tpl.replace('__GATEWAY_TOKEN__', token)
|
landing = landing_tpl.replace('__GATEWAY_TOKEN__', token)
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ configuration:
|
|||||||
name: Активиране на уеб терминал
|
name: Активиране на уеб терминал
|
||||||
description: Активиране на уеб терминал бутона в Home Assistant (Ingress) чрез ttyd
|
description: Активиране на уеб терминал бутона в Home Assistant (Ingress) чрез ttyd
|
||||||
|
|
||||||
|
terminal_port:
|
||||||
|
name: Порт на терминал
|
||||||
|
description: Номер на порт за уеб терминала (по подразбиране - 7681). Променете, ако този порт е в конфликт с друга услуга.
|
||||||
|
|
||||||
gateway_public_url:
|
gateway_public_url:
|
||||||
name: Публичен URL на Gateway
|
name: Публичен URL на Gateway
|
||||||
description: Публичен базов URL за отваряне на Gateway уеб интерфейса в нов таб (не вграден). Пример - https://example.duckdns.org:12345 или http://192.168.1.10:18789
|
description: Публичен базов URL за отваряне на Gateway уеб интерфейса в нов таб (не вграден). Пример - https://example.duckdns.org:12345 или http://192.168.1.10:18789
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ configuration:
|
|||||||
name: Web-Terminal aktivieren
|
name: Web-Terminal aktivieren
|
||||||
description: Web-Terminal-Schaltfläche in Home Assistant (Ingress) über ttyd aktivieren
|
description: Web-Terminal-Schaltfläche in Home Assistant (Ingress) über ttyd aktivieren
|
||||||
|
|
||||||
|
terminal_port:
|
||||||
|
name: Terminal-Port
|
||||||
|
description: Portnummer für das Web-Terminal (Standard - 7681). Ändern Sie diese, wenn dieser Port mit einem anderen Dienst in Konflikt steht.
|
||||||
|
|
||||||
gateway_public_url:
|
gateway_public_url:
|
||||||
name: Öffentliche Gateway-URL
|
name: Öffentliche Gateway-URL
|
||||||
description: Öffentliche Basis-URL zum Öffnen der Gateway-Weboberfläche in einem neuen Tab (nicht eingebettet). Beispiel - https://example.duckdns.org:12345 oder http://192.168.1.10:18789
|
description: Öffentliche Basis-URL zum Öffnen der Gateway-Weboberfläche in einem neuen Tab (nicht eingebettet). Beispiel - https://example.duckdns.org:12345 oder http://192.168.1.10:18789
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ configuration:
|
|||||||
name: Enable Web Terminal
|
name: Enable Web Terminal
|
||||||
description: Enable web terminal Button inside Home Assistant (Ingress) via ttyd
|
description: Enable web terminal Button inside Home Assistant (Ingress) via ttyd
|
||||||
|
|
||||||
|
terminal_port:
|
||||||
|
name: Terminal Port
|
||||||
|
description: Port number for the web terminal (default - 7681). Change if this port conflicts with another service.
|
||||||
|
|
||||||
gateway_public_url:
|
gateway_public_url:
|
||||||
name: Gateway Public URL
|
name: Gateway Public URL
|
||||||
description: Public base URL for opening the Gateway Web UI in a new tab (not embedded). Example - https://example.duckdns.org:12345 or http://192.168.1.10:18789
|
description: Public base URL for opening the Gateway Web UI in a new tab (not embedded). Example - https://example.duckdns.org:12345 or http://192.168.1.10:18789
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ configuration:
|
|||||||
name: Activar terminal web
|
name: Activar terminal web
|
||||||
description: Activar botón de terminal web dentro de Home Assistant (Ingress) mediante ttyd
|
description: Activar botón de terminal web dentro de Home Assistant (Ingress) mediante ttyd
|
||||||
|
|
||||||
|
terminal_port:
|
||||||
|
name: Puerto del terminal
|
||||||
|
description: Número de puerto para el terminal web (predeterminado - 7681). Cambie si este puerto entra en conflicto con otro servicio.
|
||||||
|
|
||||||
gateway_public_url:
|
gateway_public_url:
|
||||||
name: URL pública del Gateway
|
name: URL pública del Gateway
|
||||||
description: URL base pública para abrir la interfaz web del Gateway en una nueva pestaña (no integrada). Ejemplo - https://example.duckdns.org:12345 o http://192.168.1.10:18789
|
description: URL base pública para abrir la interfaz web del Gateway en una nueva pestaña (no integrada). Ejemplo - https://example.duckdns.org:12345 o http://192.168.1.10:18789
|
||||||
|
|||||||
Reference in New Issue
Block a user