refactor: restructure into hermes/ and openclaw/ directories
- Split cloudinit.tf into cloudinit-hermes.tf and cloudinit-openclaw.tf - Split variables.tf into variables-common.tf, variables-hermes.tf, variables-openclaw.tf - Move templates into hermes/templates/ and openclaw/templates/ - Move models/ into openclaw/models/ - Move hermes-openclaw.json to openclaw/openclaw-reference.json - Move hermes docs to hermes/docs/ - OpenClaw cloudinit now uses variables instead of hardcoded values - All 48 variable references verified against definitions
This commit is contained in:
parent
8a94313bd3
commit
ea73745147
21 changed files with 277 additions and 216 deletions
56
openclaw/models/anthropic.json
Normal file
56
openclaw/models/anthropic.json
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"anthropic": {
|
||||
"baseUrl": "https://api.anthropic.com/v1",
|
||||
"api": "anthropic-messages",
|
||||
"models": [
|
||||
{
|
||||
"id": "claude-3.5-sonnet",
|
||||
"name": "Claude 3.5 Sonnet",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "claude-3.5-sonnet-20241022",
|
||||
"name": "Claude 3.5 Sonnet (New)",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "claude-3.5-haiku",
|
||||
"name": "Claude 3.5 Haiku",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "claude-3-opus",
|
||||
"name": "Claude 3 Opus",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "claude-3-sonnet",
|
||||
"name": "Claude 3 Sonnet",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "claude-3-haiku",
|
||||
"name": "Claude 3 Haiku",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 4096
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
90
openclaw/models/combined.json
Normal file
90
openclaw/models/combined.json
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"venice": {
|
||||
"baseUrl": "https://api.venice.ai/api/v1",
|
||||
"api": "openai-completions",
|
||||
"models": {
|
||||
"zai-org-glm-5": {
|
||||
"name": "GLM 5",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 202752,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
"olafangensan-glm-4.7-flash-heretic": {
|
||||
"name": "GLM 4.7 Flash Heretic",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
"kimi-k2-5": {
|
||||
"name": "Kimi K2.5",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 256000,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
"deepseek-v3.2": {
|
||||
"name": "DeepSeek V3.2",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 64000,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
}
|
||||
},
|
||||
"openai": {
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"api": "openai-completions",
|
||||
"models": {
|
||||
"gpt-4o": {
|
||||
"name": "GPT-4o",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
"gpt-4o-mini": {
|
||||
"name": "GPT-4o Mini",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
"o1": {
|
||||
"name": "o1",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 100000
|
||||
},
|
||||
"o1-mini": {
|
||||
"name": "o1 Mini",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 65536
|
||||
}
|
||||
}
|
||||
},
|
||||
"anthropic": {
|
||||
"baseUrl": "https://api.anthropic.com/v1",
|
||||
"api": "anthropic-messages",
|
||||
"models": {
|
||||
"claude-3.5-sonnet": {
|
||||
"name": "Claude 3.5 Sonnet",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
"claude-3.5-haiku": {
|
||||
"name": "Claude 3.5 Haiku",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
openclaw/models/gemini.json
Normal file
40
openclaw/models/gemini.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"gemini": {
|
||||
"baseUrl": "https://generativelanguage.googleapis.com/v1beta",
|
||||
"api": "google-ai",
|
||||
"models": [
|
||||
{
|
||||
"id": "gemini-2.0-flash",
|
||||
"name": "Gemini 2.0 Flash",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image", "video"],
|
||||
"contextWindow": 1048576,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "gemini-1.5-pro",
|
||||
"name": "Gemini 1.5 Pro",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image", "video", "audio"],
|
||||
"contextWindow": 2097152,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
{
|
||||
"id": "gemini-1.5-flash",
|
||||
"name": "Gemini 1.5 Flash",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image", "video", "audio"],
|
||||
"contextWindow": 1048576,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "gemini-1.5-flash-8b",
|
||||
"name": "Gemini 1.5 Flash 8B",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 1048576,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
56
openclaw/models/groq.json
Normal file
56
openclaw/models/groq.json
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"groq": {
|
||||
"baseUrl": "https://api.groq.com/openai/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "llama-3.3-70b-versatile",
|
||||
"name": "Llama 3.3 70B Versatile",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "llama-3.1-70b-versatile",
|
||||
"name": "Llama 3.1 70B Versatile",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "llama-3.1-8b-instant",
|
||||
"name": "Llama 3.1 8B Instant",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "mixtral-8x7b-32768",
|
||||
"name": "Mixtral 8x7B",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 32768,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "gemma2-9b-it",
|
||||
"name": "Gemma 2 9B",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 8192,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "deepseek-r1-distill-llama-70b",
|
||||
"name": "DeepSeek R1 Distill Llama 70B",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
72
openclaw/models/openai.json
Normal file
72
openclaw/models/openai.json
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"openai": {
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "gpt-4o",
|
||||
"name": "GPT-4o",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image", "audio"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini",
|
||||
"name": "GPT-4o Mini",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo",
|
||||
"name": "GPT-4 Turbo",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "gpt-4",
|
||||
"name": "GPT-4",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 8192,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "o1",
|
||||
"name": "o1",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 100000
|
||||
},
|
||||
{
|
||||
"id": "o1-mini",
|
||||
"name": "o1 Mini",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
{
|
||||
"id": "o1-pro",
|
||||
"name": "o1 Pro",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 100000
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo",
|
||||
"name": "GPT-3.5 Turbo",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 16385,
|
||||
"maxTokens": 4096
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
72
openclaw/models/openrouter.json
Normal file
72
openclaw/models/openrouter.json
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"openrouter": {
|
||||
"baseUrl": "https://openrouter.ai/api/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "anthropic/claude-3.5-sonnet",
|
||||
"name": "Claude 3.5 Sonnet (via OpenRouter)",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 200000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "openai/gpt-4o",
|
||||
"name": "GPT-4o (via OpenRouter)",
|
||||
"reasoning": false,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
{
|
||||
"id": "google/gemini-pro-1.5",
|
||||
"name": "Gemini Pro 1.5 (via OpenRouter)",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image", "video"],
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "meta-llama/llama-3.1-405b-instruct",
|
||||
"name": "Llama 3.1 405B (via OpenRouter)",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "deepseek/deepseek-r1",
|
||||
"name": "DeepSeek R1 (via OpenRouter)",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 64000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "qwen/qwen-2.5-72b-instruct",
|
||||
"name": "Qwen 2.5 72B (via OpenRouter)",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "mistralai/mistral-large",
|
||||
"name": "Mistral Large (via OpenRouter)",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "x-ai/grok-2",
|
||||
"name": "Grok 2 (via OpenRouter)",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
80
openclaw/models/venice.json
Normal file
80
openclaw/models/venice.json
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
{
|
||||
"venice": {
|
||||
"baseUrl": "https://api.venice.ai/api/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "zai-org-glm-5",
|
||||
"name": "GLM 5",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 202752,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "zai-org-glm-4.7",
|
||||
"name": "GLM 4.7",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 202752,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "olafangensan-glm-4.7-flash-heretic",
|
||||
"name": "GLM 4.7 Flash Heretic",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "kimi-k2-5",
|
||||
"name": "Kimi K2.5",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 256000,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
{
|
||||
"id": "deepseek-v3.2",
|
||||
"name": "DeepSeek V3.2",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 64000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "qwen3-coder-480b-a35b-instruct",
|
||||
"name": "Qwen3 Coder 480B",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 16384
|
||||
},
|
||||
{
|
||||
"id": "llama-3.1-405b",
|
||||
"name": "Llama 3.1 405B",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "llama-3.1-70b",
|
||||
"name": "Llama 3.1 70B",
|
||||
"reasoning": false,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 4096
|
||||
},
|
||||
{
|
||||
"id": "mistral-123b",
|
||||
"name": "Mistral Large 2",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
122
openclaw/openclaw-reference.json
Normal file
122
openclaw/openclaw-reference.json
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"auth": {
|
||||
"profiles": {
|
||||
"venice:default": {
|
||||
"provider": "venice",
|
||||
"mode": "api_key"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"mode": "merge",
|
||||
"providers": {
|
||||
"venice": {
|
||||
"baseUrl": "https://api.venice.ai/api/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "zai-org-glm-5",
|
||||
"name": "GLM 5",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 202752,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "zai-org-glm-4.7",
|
||||
"name": "GLM 4.7",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 202752,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "olafangensan-glm-4.7-flash-heretic",
|
||||
"name": "GLM 4.7 Flash Heretic",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "kimi-k2-5",
|
||||
"name": "Kimi K2.5",
|
||||
"reasoning": true,
|
||||
"input": ["text", "image"],
|
||||
"contextWindow": 256000,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
{
|
||||
"id": "deepseek-v3.2",
|
||||
"name": "DeepSeek V3.2",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 64000,
|
||||
"maxTokens": 8192
|
||||
},
|
||||
{
|
||||
"id": "qwen3-coder-480b-a35b-instruct",
|
||||
"name": "Qwen3 Coder 480B",
|
||||
"reasoning": true,
|
||||
"input": ["text"],
|
||||
"contextWindow": 131072,
|
||||
"maxTokens": 16384
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "venice/olafangensan-glm-4.7-flash-heretic",
|
||||
"fallbacks": ["venice/zai-org-glm-5"]
|
||||
},
|
||||
"workspace": "/home/openclaw/.openclaw/workspace"
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "hermes",
|
||||
"default": true,
|
||||
"workspace": "/home/openclaw/.openclaw/workspace"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"web": {
|
||||
"search": {
|
||||
"enabled": true,
|
||||
"provider": "brave",
|
||||
"apiKey": "${BRAVE_SEARCH_API_KEY}"
|
||||
},
|
||||
"fetch": { "enabled": true }
|
||||
},
|
||||
"exec": {
|
||||
"security": "allowlist",
|
||||
"ask": "on-miss"
|
||||
}
|
||||
},
|
||||
"messages": {
|
||||
"queue": { "mode": "collect" },
|
||||
"ackReactionScope": "all"
|
||||
},
|
||||
"channels": {
|
||||
"discord": {
|
||||
"enabled": true,
|
||||
"token": "${DISCORD_BOT_TOKEN}",
|
||||
"groupPolicy": "allowlist",
|
||||
"guilds": {
|
||||
"YOUR_GUILD_ID": {
|
||||
"requireMention": false,
|
||||
"users": ["YOUR_USER_ID"],
|
||||
"channels": { "*": { "allow": true } }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"mode": "local",
|
||||
"bind": "loopback"
|
||||
}
|
||||
}
|
||||
372
openclaw/templates/userdata-openclaw.tpl
Normal file
372
openclaw/templates/userdata-openclaw.tpl
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
#cloud-config
|
||||
# OpenClaw Gateway Bootstrap
|
||||
|
||||
# Update packages
|
||||
package_update: true
|
||||
package_upgrade: true
|
||||
|
||||
# Install required packages
|
||||
packages:
|
||||
- curl
|
||||
- git
|
||||
- fail2ban
|
||||
- ufw
|
||||
- jq
|
||||
- gnupg
|
||||
- ca-certificates
|
||||
- software-properties-common
|
||||
|
||||
# Create admin user (if different from root)
|
||||
users:
|
||||
- name: ${admin_user}
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
shell: /bin/bash
|
||||
ssh_authorized_keys: ${jsonencode(admin_ssh_keys)}
|
||||
groups: [sudo, systemd-journal]
|
||||
|
||||
# Write system configuration files
|
||||
write_files:
|
||||
# SSH hardening configuration
|
||||
- path: /etc/ssh/sshd_config.d/99-hardening.conf
|
||||
content: |
|
||||
# SSH Security Hardening
|
||||
Port ${ssh_port}
|
||||
PermitRootLogin no
|
||||
PasswordAuthentication no
|
||||
PubkeyAuthentication yes
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
ChallengeResponseAuthentication no
|
||||
UsePAM yes
|
||||
X11Forwarding no
|
||||
PrintMotd no
|
||||
AcceptEnv LANG LC_*
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
permissions: '0644'
|
||||
|
||||
# Fail2ban SSH configuration
|
||||
%{if enable_fail2ban}
|
||||
- path: /etc/fail2ban/jail.d/sshd.local
|
||||
content: |
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ${ssh_port}
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 3
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
permissions: '0644'
|
||||
%{endif}
|
||||
|
||||
# OpenClaw environment file
|
||||
- path: /etc/openclaw.env
|
||||
content: |
|
||||
# Secrets injected during provisioning - DO NOT commit to version control
|
||||
|
||||
# Inference API keys
|
||||
%{if venice_api_key != ""}
|
||||
VENICE_API_KEY=${venice_api_key}
|
||||
%{endif}
|
||||
|
||||
%{if brave_search_api_key != ""}
|
||||
BRAVE_SEARCH_API_KEY=${brave_search_api_key}
|
||||
%{endif}
|
||||
|
||||
# Discord configuration
|
||||
%{if discord_bot_token != ""}
|
||||
DISCORD_BOT_TOKEN=${discord_bot_token}
|
||||
%{endif}
|
||||
%{if discord_server_id != ""}
|
||||
DISCORD_SERVER_ID=${discord_server_id}
|
||||
%{endif}
|
||||
%{if length(discord_user_id) > 0}
|
||||
DISCORD_USER_ID=${jsonencode(discord_user_id)}
|
||||
%{endif}
|
||||
|
||||
# Tailscale auth key (if enabled)
|
||||
%{if enable_tailscale && tailscale_auth_key != ""}
|
||||
TAILSCALE_AUTH_KEY=${tailscale_auth_key}
|
||||
%{endif}
|
||||
permissions: '0600'
|
||||
|
||||
# OpenClaw configuration file (uses env var references for secrets)
|
||||
- path: /home/${admin_user}/.openclaw/openclaw.json
|
||||
content: |
|
||||
{
|
||||
"auth": {
|
||||
"profiles": {
|
||||
"venice:default": {
|
||||
"provider": "venice",
|
||||
"mode": "api_key"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"mode": "merge",
|
||||
"providers": ${models_config}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "${primary_model}",
|
||||
"fallbacks": ${fallback_models}
|
||||
},
|
||||
"workspace": "/home/${admin_user}/.openclaw/workspace"
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "${agent_name}",
|
||||
"default": true,
|
||||
"workspace": "/home/${admin_user}/.openclaw/workspace"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"web": {
|
||||
"search": {
|
||||
"enabled": true,
|
||||
"provider": "brave",
|
||||
"apiKey": "$${BRAVE_SEARCH_API_KEY}"
|
||||
},
|
||||
"fetch": { "enabled": true }
|
||||
},
|
||||
"exec": {
|
||||
"security": "allowlist",
|
||||
"ask": "on-miss"
|
||||
}
|
||||
},
|
||||
"messages": {
|
||||
"queue": { "mode": "collect" },
|
||||
"ackReactionScope": "all"
|
||||
},
|
||||
"channels": {
|
||||
"discord": {
|
||||
"enabled": true,
|
||||
"token": "$${DISCORD_BOT_TOKEN}",
|
||||
"groupPolicy": "allowlist",
|
||||
"guilds": {
|
||||
"${discord_server_id}": {
|
||||
"requireMention": false,
|
||||
"users": ${jsonencode(discord_user_id)},
|
||||
"channels": { "*": { "allow": true } }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"mode": "local",
|
||||
"bind": "loopback"
|
||||
}
|
||||
}
|
||||
permissions: '0644'
|
||||
|
||||
# Systemd service for OpenClaw Gateway
|
||||
- path: /etc/systemd/system/openclaw-gateway.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=OpenClaw Gateway Service
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/openclaw gateway run
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=openclaw-gateway
|
||||
EnvironmentFile=/etc/openclaw.env
|
||||
WorkingDirectory=/home/${admin_user}/.openclaw
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
permissions: '0644'
|
||||
|
||||
# Health check script
|
||||
- path: /usr/local/bin/openclaw-health-check.sh
|
||||
content: |
|
||||
#!/bin/bash
|
||||
# OpenClaw Gateway Health Check
|
||||
set -e
|
||||
|
||||
echo "=== OpenClaw Health Check ==="
|
||||
echo ""
|
||||
|
||||
# Check if OpenClaw is installed
|
||||
if command -v openclaw &> /dev/null; then
|
||||
echo "✓ OpenClaw installed: $(openclaw --version)"
|
||||
else
|
||||
echo "✗ OpenClaw not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if gateway is running
|
||||
if systemctl is-active --quiet openclaw-gateway; then
|
||||
echo "✓ Gateway service running"
|
||||
else
|
||||
echo "✗ Gateway service not running"
|
||||
fi
|
||||
|
||||
# Check if gateway is listening
|
||||
if lsof -i :18789 > /dev/null 2>&1; then
|
||||
echo "✓ Gateway listening on port 18789"
|
||||
else
|
||||
echo "✗ Gateway not listening on port 18789"
|
||||
fi
|
||||
|
||||
# Check firewall
|
||||
if ufw status | grep -q "Status: active"; then
|
||||
echo "✓ Firewall active"
|
||||
else
|
||||
echo "⚠ Firewall not active"
|
||||
fi
|
||||
|
||||
# Check fail2ban
|
||||
%{if enable_fail2ban}
|
||||
if systemctl is-active --quiet fail2ban; then
|
||||
echo "✓ fail2ban running"
|
||||
else
|
||||
echo "⚠ fail2ban not running"
|
||||
fi
|
||||
%{endif}
|
||||
|
||||
echo ""
|
||||
echo "=== End Health Check ==="
|
||||
permissions: '0755'
|
||||
|
||||
%{if enable_swap}
|
||||
# Swap creation script
|
||||
- path: /usr/local/bin/create-swap.sh
|
||||
content: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
if [ ! -f /swapfile ]; then
|
||||
fallocate -l ${swap_size}G /swapfile
|
||||
chmod 600 /swapfile
|
||||
mkswap /swapfile
|
||||
swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
echo "Created ${swap_size}GB swap"
|
||||
else
|
||||
echo "Swap already exists"
|
||||
fi
|
||||
permissions: '0755'
|
||||
%{endif}
|
||||
%{if enable_tailscale}
|
||||
# Tailscale setup script
|
||||
- path: /usr/local/bin/setup-tailscale.sh
|
||||
content: |
|
||||
#!/bin/bash
|
||||
set -e
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
tailscale up --authkey=${tailscale_auth_key} --ssh
|
||||
|
||||
# Wait for Tailscale to connect
|
||||
sleep 5
|
||||
|
||||
# Enable Tailscale Serve for gateway access
|
||||
# This exposes the gateway on the tailnet via HTTPS
|
||||
tailscale serve --bg 18789 || echo "Note: Tailscale serve may require 'Serve' to be enabled in admin console"
|
||||
|
||||
echo "Tailscale configured and serving on port 18789"
|
||||
permissions: '0755'
|
||||
%{endif}
|
||||
|
||||
# Run commands
|
||||
runcmd:
|
||||
# Create admin user home directory
|
||||
- mkdir -p /home/${admin_user}
|
||||
- chown ${admin_user}:${admin_user} /home/${admin_user}
|
||||
|
||||
%{if enable_swap}
|
||||
# Create swapfile
|
||||
- /usr/local/bin/create-swap.sh
|
||||
%{endif}
|
||||
|
||||
# Install Node.js ${node_version}
|
||||
- curl -fsSL https://deb.nodesource.com/setup_${node_version}.x | bash -
|
||||
- apt-get install -y nodejs
|
||||
- node --version
|
||||
- npm --version
|
||||
|
||||
# Install OpenClaw
|
||||
%{if openclaw_version == "latest"}
|
||||
- curl -fsSL https://openclaw.ai/install.sh | bash
|
||||
%{else}
|
||||
%{if openclaw_version == "lts"}
|
||||
- curl -fsSL https://openclaw.ai/install.sh | bash -s -- --version lts
|
||||
%{else}
|
||||
- curl -fsSL https://openclaw.ai/install.sh | bash -s -- --version ${openclaw_version}
|
||||
%{endif}
|
||||
%{endif}
|
||||
- openclaw --version || echo "OpenClaw installed, needs configuration"
|
||||
|
||||
# Create OpenClaw config directory
|
||||
- mkdir -p /home/${admin_user}/.openclaw/workspace
|
||||
- chown -R ${admin_user}:${admin_user} /home/${admin_user}/.openclaw
|
||||
|
||||
# Configure firewall (SSH only)
|
||||
- ufw default deny incoming
|
||||
- ufw default allow outgoing
|
||||
- ufw allow ${ssh_port}/tcp
|
||||
- ufw --force enable
|
||||
|
||||
%{if enable_fail2ban}
|
||||
# Enable fail2ban
|
||||
- systemctl enable fail2ban
|
||||
- systemctl start fail2ban
|
||||
%{endif}
|
||||
|
||||
%{if enable_unattended_upgrades}
|
||||
# Enable automatic security updates
|
||||
- apt-get install -y unattended-upgrades
|
||||
- dpkg-reconfigure --priority=low unattended-upgrades
|
||||
%{endif}
|
||||
|
||||
# Set up SSH hardening
|
||||
- systemctl restart sshd
|
||||
|
||||
%{if enable_tailscale}
|
||||
# Install and configure Tailscale
|
||||
- /usr/local/bin/setup-tailscale.sh
|
||||
%{endif}
|
||||
|
||||
# Set permissions on environment file
|
||||
- chown root:root /etc/openclaw.env
|
||||
- chmod 600 /etc/openclaw.env
|
||||
|
||||
# Enable and start OpenClaw gateway service
|
||||
# Config is pre-seeded, so gateway can start immediately
|
||||
- systemctl daemon-reload
|
||||
- systemctl enable openclaw-gateway.service
|
||||
- systemctl start openclaw-gateway.service
|
||||
|
||||
# Print completion message
|
||||
- |
|
||||
echo ""
|
||||
echo "======================================="
|
||||
echo " OpenClaw Gateway Bootstrap Complete!"
|
||||
echo "======================================="
|
||||
echo ""
|
||||
echo "Server is ready."
|
||||
echo ""
|
||||
%{if enable_tailscale}
|
||||
echo "Access via Tailscale:"
|
||||
echo " https://${server_name}.TAILNET.ts.net/"
|
||||
echo ""
|
||||
echo "If Tailscale Serve didn't start, run:"
|
||||
echo " sudo tailscale serve --bg 18789"
|
||||
echo ""
|
||||
%{else}
|
||||
echo "SSH into this server:"
|
||||
echo " ${ssh_port != 22 ? "ssh -p ${ssh_port}" : "ssh"} ${admin_user}@$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)"
|
||||
echo ""
|
||||
%{endif}
|
||||
echo "Check gateway status:"
|
||||
echo " systemctl status openclaw-gateway"
|
||||
echo ""
|
||||
echo "View logs:"
|
||||
echo " journalctl -u openclaw-gateway -f"
|
||||
echo ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue