merge new gateway configs from dev build
This commit is contained in:
@@ -43,9 +43,10 @@ RUN npm config set fund false && npm config set audit false \
|
||||
&& npm install -g openclaw@2026.1.30
|
||||
|
||||
COPY run.sh /run.sh
|
||||
COPY oc_config_helper.py /oc_config_helper.py
|
||||
COPY nginx.conf.tpl /etc/nginx/nginx.conf.tpl
|
||||
COPY landing.html.tpl /etc/nginx/landing.html.tpl
|
||||
RUN chmod +x /run.sh \
|
||||
RUN chmod +x /run.sh /oc_config_helper.py \
|
||||
&& mkdir -p /run/nginx
|
||||
|
||||
CMD [ "/run.sh" ]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: OpenClaw Assistant
|
||||
version: "0.5.25"
|
||||
version: "0.5.26"
|
||||
slug: openclaw_assistant
|
||||
description: Run OpenClaw Assistant (OpenClaw-compatible) as a Home Assistant add-on.
|
||||
url: https://github.com/techartdev/OpenClawHomeAssistant
|
||||
@@ -47,6 +47,15 @@ options:
|
||||
clean_session_locks_on_start: true
|
||||
clean_session_locks_on_exit: true
|
||||
|
||||
# Gateway network bind mode:
|
||||
# - loopback: bind to 127.0.0.1 only (local access only, more secure)
|
||||
# - lan: bind to all interfaces (accessible from local network)
|
||||
# Default is loopback for security.
|
||||
gateway_bind_mode: loopback
|
||||
|
||||
# Gateway port to listen on
|
||||
gateway_port: 18789
|
||||
|
||||
|
||||
schema:
|
||||
timezone: str
|
||||
@@ -60,4 +69,6 @@ schema:
|
||||
|
||||
clean_session_locks_on_start: bool?
|
||||
clean_session_locks_on_exit: bool?
|
||||
gateway_bind_mode: list(loopback|lan)?
|
||||
gateway_port: int(1,65535)?
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
OpenClaw config helper for Home Assistant add-on.
|
||||
Safely reads/writes openclaw.json without corrupting it.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
CONFIG_PATH = Path(os.environ.get("OPENCLAW_CONFIG_PATH", "/config/.openclaw/openclaw.json"))
|
||||
|
||||
|
||||
|
||||
def read_config():
|
||||
"""Read and parse openclaw.json."""
|
||||
if not CONFIG_PATH.exists():
|
||||
return None
|
||||
try:
|
||||
return json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
|
||||
except (json.JSONDecodeError, IOError) as e:
|
||||
print(f"ERROR: Failed to read config: {e}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
|
||||
def write_config(cfg):
|
||||
"""Write config back to file with nice formatting."""
|
||||
try:
|
||||
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
CONFIG_PATH.write_text(json.dumps(cfg, indent=2) + "\n", encoding="utf-8")
|
||||
return True
|
||||
except IOError as e:
|
||||
print(f"ERROR: Failed to write config: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def get_gateway_setting(key, default=None):
|
||||
"""Get a gateway setting from config."""
|
||||
cfg = read_config()
|
||||
if cfg is None:
|
||||
return default
|
||||
return cfg.get("gateway", {}).get(key, default)
|
||||
|
||||
|
||||
def set_gateway_setting(key, value):
|
||||
"""Set a gateway setting, preserving other config."""
|
||||
cfg = read_config()
|
||||
if cfg is None:
|
||||
cfg = {}
|
||||
|
||||
if "gateway" not in cfg:
|
||||
cfg["gateway"] = {}
|
||||
|
||||
cfg["gateway"][key] = value
|
||||
return write_config(cfg)
|
||||
|
||||
|
||||
def apply_bind_mode_settings(bind_mode: str, port: int):
|
||||
"""
|
||||
Apply bind mode settings to OpenClaw config.
|
||||
|
||||
Args:
|
||||
bind_mode: "loopback" or "lan"
|
||||
port: Port number to listen on (must be 1-65535)
|
||||
"""
|
||||
# Validate bind mode
|
||||
if bind_mode not in ["loopback", "lan"]:
|
||||
print(f"ERROR: Invalid bind_mode '{bind_mode}'. Must be 'loopback' or 'lan'")
|
||||
return False
|
||||
|
||||
# Validate port range
|
||||
if port < 1 or port > 65535:
|
||||
print(f"ERROR: Invalid port {port}. Must be between 1 and 65535")
|
||||
return False
|
||||
|
||||
cfg = read_config()
|
||||
if cfg is None:
|
||||
cfg = {}
|
||||
|
||||
if "gateway" not in cfg:
|
||||
cfg["gateway"] = {}
|
||||
|
||||
gateway = cfg["gateway"]
|
||||
|
||||
current_bind = gateway.get("bind", "")
|
||||
current_port = gateway.get("port", 18789)
|
||||
|
||||
changes = []
|
||||
|
||||
if current_bind != bind_mode:
|
||||
gateway["bind"] = bind_mode
|
||||
changes.append(f"bind: {current_bind} -> {bind_mode}")
|
||||
|
||||
# Always update port when it differs from the desired value
|
||||
if current_port != port:
|
||||
gateway["port"] = port
|
||||
changes.append(f"port: {current_port} -> {port}")
|
||||
|
||||
if changes:
|
||||
if write_config(cfg):
|
||||
print(f"INFO: Updated gateway settings: {', '.join(changes)}")
|
||||
return True
|
||||
else:
|
||||
print("ERROR: Failed to write config")
|
||||
return False
|
||||
else:
|
||||
print(f"INFO: Gateway settings already correct (bind={bind_mode}, port={port})")
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI entry point for use by run.sh"""
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: oc_config_helper.py <command> [args...]")
|
||||
sys.exit(1)
|
||||
|
||||
cmd = sys.argv[1]
|
||||
|
||||
if cmd == "apply-bind-mode":
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: oc_config_helper.py apply-bind-mode <loopback|lan> <port>")
|
||||
sys.exit(1)
|
||||
bind_mode = sys.argv[2]
|
||||
port = int(sys.argv[3])
|
||||
success = apply_bind_mode_settings(bind_mode, port)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif cmd == "get":
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: oc_config_helper.py get <key>")
|
||||
sys.exit(1)
|
||||
key = sys.argv[2]
|
||||
value = get_gateway_setting(key)
|
||||
if value is not None:
|
||||
print(value)
|
||||
sys.exit(0)
|
||||
|
||||
elif cmd == "set":
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: oc_config_helper.py set <key> <value>")
|
||||
sys.exit(1)
|
||||
key = sys.argv[2]
|
||||
value = sys.argv[3]
|
||||
# Try to convert to int if it looks like a number
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
pass
|
||||
success = set_gateway_setting(key, value)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
else:
|
||||
print(f"Unknown command: {cmd}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -27,6 +27,10 @@ ROUTER_KEY=$(jq -r '.router_ssh_key_path // "/data/keys/router_ssh"' "$OPTIONS_F
|
||||
CLEAN_LOCKS_ON_START=$(jq -r '.clean_session_locks_on_start // true' "$OPTIONS_FILE")
|
||||
CLEAN_LOCKS_ON_EXIT=$(jq -r '.clean_session_locks_on_exit // true' "$OPTIONS_FILE")
|
||||
|
||||
# Gateway bind mode (loopback or lan)
|
||||
GATEWAY_BIND_MODE=$(jq -r '.gateway_bind_mode // "loopback"' "$OPTIONS_FILE")
|
||||
GATEWAY_PORT=$(jq -r '.gateway_port // 18789' "$OPTIONS_FILE")
|
||||
|
||||
export TZ="$TZNAME"
|
||||
|
||||
# Reduce risk of secrets ending up in logs
|
||||
@@ -170,6 +174,8 @@ cfg_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
cfg = {
|
||||
"gateway": {
|
||||
"mode": "local",
|
||||
"port": 18789,
|
||||
"bind": "loopback",
|
||||
"auth": {
|
||||
"mode": "token",
|
||||
"token": secrets.token_urlsafe(24)
|
||||
@@ -182,6 +188,35 @@ print("INFO: Wrote minimal OpenClaw config (gateway.mode=local, auth.token gener
|
||||
PY
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Apply gateway LAN mode settings safely using helper script
|
||||
# This updates gateway.bind and gateway.port without touching other settings
|
||||
# ------------------------------------------------------------------------------
|
||||
export OPENCLAW_CONFIG_PATH="/config/.openclaw/openclaw.json"
|
||||
|
||||
# Find the helper script (copied to root in Dockerfile, or fallback to add-on dir)
|
||||
HELPER_PATH="/oc_config_helper.py"
|
||||
if [ ! -f "$HELPER_PATH" ] && [ -f "$(dirname "$0")/oc_config_helper.py" ]; then
|
||||
HELPER_PATH="$(dirname "$0")/oc_config_helper.py"
|
||||
fi
|
||||
|
||||
if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
||||
if [ -f "$HELPER_PATH" ]; then
|
||||
if ! python3 "$HELPER_PATH" apply-bind-mode "$GATEWAY_BIND_MODE" "$GATEWAY_PORT"; then
|
||||
rc=$?
|
||||
echo "ERROR: Failed to apply gateway bind mode via oc_config_helper.py (exit code ${rc})."
|
||||
echo "ERROR: Gateway bind configuration may be incorrect; aborting startup."
|
||||
exit "${rc}"
|
||||
fi
|
||||
else
|
||||
echo "WARN: oc_config_helper.py not found, cannot apply gateway settings"
|
||||
echo "INFO: Ensure the add-on image includes oc_config_helper.py and restart"
|
||||
fi
|
||||
else
|
||||
echo "WARN: OpenClaw config not found at $OPENCLAW_CONFIG_PATH, cannot apply gateway settings"
|
||||
echo "INFO: Run 'openclaw onboard' first, then restart the add-on"
|
||||
fi
|
||||
|
||||
echo "Starting OpenClaw Assistant gateway (openclaw)..."
|
||||
openclaw gateway run &
|
||||
GW_PID=$!
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
configuration:
|
||||
timezone:
|
||||
name: Часова зона
|
||||
description: Часова зона за добавката (напр. Europe/Sofia, America/New_York)
|
||||
|
||||
enable_terminal:
|
||||
name: Активиране на уеб терминал
|
||||
description: Активиране на уеб терминал бутона в Home Assistant (Ingress) чрез ttyd
|
||||
|
||||
gateway_public_url:
|
||||
name: Публичен URL на Gateway
|
||||
description: Публичен базов URL за отваряне на Gateway уеб интерфейса в нов таб (не вграден). Пример - https://example.duckdns.org:12345 или http://192.168.1.10:18789
|
||||
|
||||
homeassistant_token:
|
||||
name: Home Assistant токен
|
||||
description: Опционално - дълготраен токен на Home Assistant за локални API скриптове/инструменти
|
||||
|
||||
router_ssh_host:
|
||||
name: SSH хост на рутер
|
||||
description: Опционално - SSH име на хост или IP адрес на рутер/защитна стена
|
||||
|
||||
router_ssh_user:
|
||||
name: SSH потребител на рутер
|
||||
description: Опционално - SSH потребителско име за рутер/защитна стена
|
||||
|
||||
router_ssh_key_path:
|
||||
name: Път до SSH ключ на рутер
|
||||
description: Път до SSH частен ключ за достъп до рутер (по подразбиране - /data/keys/router_ssh)
|
||||
|
||||
clean_session_locks_on_start:
|
||||
name: Изчистване на заключвания при стартиране
|
||||
description: Изчистване на остарели заключващи файлове на сесии след срив/рестарт при стартиране на добавката
|
||||
|
||||
clean_session_locks_on_exit:
|
||||
name: Изчистване на заключвания при изход
|
||||
description: Изчистване на заключващи файлове на сесии при нормално спиране на добавката
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Режим на свързване на Gateway
|
||||
description: Режим на мрежово свързване - loopback (само 127.0.0.1, по-сигурно) или lan (всички интерфейси, достъпно от локалната мрежа)
|
||||
|
||||
gateway_port:
|
||||
name: Порт на Gateway
|
||||
description: Номер на порт, на който OpenClaw gateway да слуша (по подразбиране - 18789)
|
||||
@@ -0,0 +1,44 @@
|
||||
configuration:
|
||||
timezone:
|
||||
name: Zeitzone
|
||||
description: Zeitzone für das Add-on (z.B. Europe/Sofia, America/New_York)
|
||||
|
||||
enable_terminal:
|
||||
name: Web-Terminal aktivieren
|
||||
description: Web-Terminal-Schaltfläche in Home Assistant (Ingress) über ttyd aktivieren
|
||||
|
||||
gateway_public_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
|
||||
|
||||
homeassistant_token:
|
||||
name: Home Assistant Token
|
||||
description: Optional - Langlebiger Home Assistant Token für lokale API-Skripte/Tools
|
||||
|
||||
router_ssh_host:
|
||||
name: Router SSH-Host
|
||||
description: Optional - SSH-Hostname oder IP-Adresse des Routers/der Firewall
|
||||
|
||||
router_ssh_user:
|
||||
name: Router SSH-Benutzer
|
||||
description: Optional - SSH-Benutzername für Router/Firewall
|
||||
|
||||
router_ssh_key_path:
|
||||
name: Router SSH-Schlüsselpfad
|
||||
description: Pfad zum privaten SSH-Schlüssel für Router-Zugriff (Standard - /data/keys/router_ssh)
|
||||
|
||||
clean_session_locks_on_start:
|
||||
name: Sitzungssperren beim Start bereinigen
|
||||
description: Veraltete Sitzungssperrdateien nach Abstürzen/Neustarts beim Start des Add-ons bereinigen
|
||||
|
||||
clean_session_locks_on_exit:
|
||||
name: Sitzungssperren beim Beenden bereinigen
|
||||
description: Sitzungssperrdateien beim ordnungsgemäßen Stoppen des Add-ons bereinigen
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Gateway-Bindungsmodus
|
||||
description: Netzwerk-Bindungsmodus - loopback (nur 127.0.0.1, sicherer) oder lan (alle Schnittstellen, vom lokalen Netzwerk aus zugänglich)
|
||||
|
||||
gateway_port:
|
||||
name: Gateway-Port
|
||||
description: Portnummer, auf der das OpenClaw-Gateway lauscht (Standard - 18789)
|
||||
@@ -0,0 +1,44 @@
|
||||
configuration:
|
||||
timezone:
|
||||
name: Timezone
|
||||
description: Timezone for the add-on (e.g., Europe/Sofia, America/New_York)
|
||||
|
||||
enable_terminal:
|
||||
name: Enable Web Terminal
|
||||
description: Enable web terminal Button inside Home Assistant (Ingress) via ttyd
|
||||
|
||||
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
|
||||
|
||||
homeassistant_token:
|
||||
name: Home Assistant Token
|
||||
description: Optional - Home Assistant long-lived token for local HA API scripts/tools
|
||||
|
||||
router_ssh_host:
|
||||
name: Router SSH Host
|
||||
description: Optional - Router/firewall SSH hostname or IP address
|
||||
|
||||
router_ssh_user:
|
||||
name: Router SSH User
|
||||
description: Optional - Router/firewall SSH username
|
||||
|
||||
router_ssh_key_path:
|
||||
name: Router SSH Key Path
|
||||
description: Path to SSH private key for router access (default - /data/keys/router_ssh)
|
||||
|
||||
clean_session_locks_on_start:
|
||||
name: Clean Session Locks on Start
|
||||
description: Cleanup stale session lock files left after crashes/restarts when add-on starts
|
||||
|
||||
clean_session_locks_on_exit:
|
||||
name: Clean Session Locks on Exit
|
||||
description: Cleanup session lock files when add-on stops gracefully
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Gateway Bind Mode
|
||||
description: Network bind mode - loopback (127.0.0.1 only, more secure) or lan (all interfaces, accessible from local network)
|
||||
|
||||
gateway_port:
|
||||
name: Gateway Port
|
||||
description: Port number for the OpenClaw gateway to listen on (default - 18789)
|
||||
@@ -0,0 +1,44 @@
|
||||
configuration:
|
||||
timezone:
|
||||
name: Zona horaria
|
||||
description: Zona horaria para el complemento (ej. Europe/Sofia, America/New_York)
|
||||
|
||||
enable_terminal:
|
||||
name: Activar terminal web
|
||||
description: Activar botón de terminal web dentro de Home Assistant (Ingress) mediante ttyd
|
||||
|
||||
gateway_public_url:
|
||||
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
|
||||
|
||||
homeassistant_token:
|
||||
name: Token de Home Assistant
|
||||
description: Opcional - Token de larga duración de Home Assistant para scripts/herramientas de API local
|
||||
|
||||
router_ssh_host:
|
||||
name: Host SSH del router
|
||||
description: Opcional - Nombre de host SSH o dirección IP del router/firewall
|
||||
|
||||
router_ssh_user:
|
||||
name: Usuario SSH del router
|
||||
description: Opcional - Nombre de usuario SSH del router/firewall
|
||||
|
||||
router_ssh_key_path:
|
||||
name: Ruta de clave SSH del router
|
||||
description: Ruta a la clave privada SSH para acceso al router (predeterminado - /data/keys/router_ssh)
|
||||
|
||||
clean_session_locks_on_start:
|
||||
name: Limpiar bloqueos de sesión al iniciar
|
||||
description: Limpiar archivos de bloqueo de sesión obsoletos dejados después de fallos/reinicios cuando se inicia el complemento
|
||||
|
||||
clean_session_locks_on_exit:
|
||||
name: Limpiar bloqueos de sesión al salir
|
||||
description: Limpiar archivos de bloqueo de sesión cuando el complemento se detiene correctamente
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Modo de enlace del Gateway
|
||||
description: Modo de enlace de red - loopback (solo 127.0.0.1, más seguro) o lan (todas las interfaces, accesible desde la red local)
|
||||
|
||||
gateway_port:
|
||||
name: Puerto del Gateway
|
||||
description: Número de puerto en el que el gateway de OpenClaw escuchará (predeterminado - 18789)
|
||||
Reference in New Issue
Block a user