Initial commit — OpenClaw VM infrastructure

- ansible/: VM provisioning playbooks and roles
  - provision-vm.yml: create KVM VM from Ubuntu cloud image
  - install.yml: install OpenClaw on guest (upstream)
  - customize.yml: swappiness, virtiofs fstab, linger
  - roles/vm/: libvirt domain XML, cloud-init templates
  - inventory.yml + host_vars/zap.yml: zap instance config
- backup-openclaw-vm.sh: daily rsync + MinIO upload
- restore-openclaw-vm.sh: full redeploy from scratch
- README.md: full operational documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
William Valentin
2026-03-12 12:18:31 -07:00
commit aceeb7b542
71 changed files with 7840 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
{
"iptables": true,
"ip-forward": true,
"userland-proxy": false,
"live-restore": true,
"ip6tables": false,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"default-address-pools": [
{
"base": "172.17.0.0/12",
"size": 24
}
]
}

View File

@@ -0,0 +1,76 @@
# OpenClaw Configuration Template
# Generated by Ansible on {{ ansible_date_time.iso8601 }}
#
# For full documentation, visit: https://docs.openclaw.ai/configuration
# Connection Provider
# Options: whatsapp, telegram, signal
provider: whatsapp
# WhatsApp Configuration (if using whatsapp provider)
whatsapp:
# Phone number in international format (e.g., +4366412345678)
phone: ""
# Telegram Configuration (if using telegram provider)
telegram:
# Telegram bot token from @BotFather
token: ""
# Signal Configuration (if using signal provider)
signal:
# Signal phone number
phone: ""
# AI Model Configuration
ai:
# Model provider: anthropic, openai
provider: anthropic
# API Keys (set as environment variables or here)
# anthropic_api_key: ""
# openai_api_key: ""
# Model selection
model: claude-3-5-sonnet-20241022
# Max tokens per response
max_tokens: 4096
# Gateway Settings
gateway:
# Port for web interface
port: {{ openclaw_port }}
# Enable web UI
web_ui: true
# Logging
logging:
# Log level: debug, info, warn, error
level: info
# Log file location
file: {{ openclaw_config_dir }}/openclaw.log
# Security
security:
# Allowed phone numbers (whitelist)
# Leave empty to allow all
allowed_numbers: []
# Rate limiting
rate_limit:
enabled: true
max_requests_per_minute: 10
# Advanced Settings
advanced:
# Session timeout in minutes
session_timeout: 60
# Auto-reconnect on disconnect
auto_reconnect: true
# Keep-alive interval in seconds
keep_alive_interval: 30

View File

@@ -0,0 +1,42 @@
[Unit]
Description=OpenClaw AI Gateway
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User={{ openclaw_user }}
Group={{ openclaw_user }}
WorkingDirectory={{ openclaw_home }}
# Environment variables
Environment="PNPM_HOME={{ openclaw_home }}/.local/share/pnpm"
Environment="PATH={{ openclaw_home }}/.local/bin:{{ openclaw_home }}/.local/share/pnpm:/usr/local/bin:/usr/bin:/bin"
Environment="HOME={{ openclaw_home }}"
Environment="XDG_RUNTIME_DIR=/run/user/{{ openclaw_uid_value }}"
# DBus session bus
Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/{{ openclaw_uid_value }}/bus"
# Start command
ExecStart=openclaw gateway
# Restart policy
Restart=always
RestartSec=10
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths={{ openclaw_home }}/.openclaw
ReadWritePaths={{ openclaw_home }}/.local
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=openclaw
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,42 @@
#jinja2: lstrip_blocks: True
{% raw %}#!/bin/bash
cat << 'LOBSTER'
[0;36m
+====================================================+
| |
| [0;33mWelcome to OpenClaw! [0;31m🦞[0;36m |
| |
|[0;31m ,.---._ [0;36m|
|[0;31m ,,,, / `, [0;36m|
|[0;31m \\\ / '\_ ; [0;36m|
|[0;31m |||| /\/``-.__\;' [0;36m|
|[0;31m ::::/\/_ [0;36m|
|[0;31m {{`-.__.-'(`(^^(^^^(^ 9 `.=========' [0;36m|
|[0;31m{{{{{{ { ( ( ( ( (-----:= [0;36m|
|[0;31m {{.-'~~'-.(,(,,(,,,(__6_.'=========. [0;36m|
|[0;31m ::::\/\ [0;36m|
|[0;31m |||| \/\ ,-'/, [0;36m|
|[0;31m //// \ `` _/ ; [0;36m|
|[0;31m '''' \ ` .' [0;36m|
|[0;31m `---' [0;36m|
| |
| [0;32m✅ Installation Successful![0;36m |
| |
+====================================================+[0m
LOBSTER
echo ""
echo "🔒 Security Status:"
echo " - UFW Firewall: ENABLED"
{% endraw %}
{% if tailscale_enabled | default(false) %}
echo " - Open Ports: SSH (22) + Tailscale (41641/udp)"
{% else %}
echo " - Open Ports: SSH (22)"
{% endif %}
{% raw %}
echo " - Docker isolation: ACTIVE"
echo ""
echo "📚 Documentation: https://github.com/openclaw/openclaw-ansible"
echo ""
{% endraw %}

View File

@@ -0,0 +1,136 @@
" Vim Configuration - Generated by Ansible
" Modern, practical vim setup for development and debugging
" Basic Settings
set nocompatible " Disable vi compatibility
filetype plugin indent on " Enable file type detection
syntax on " Enable syntax highlighting
" UI Settings
set number " Show line numbers
set relativenumber " Show relative line numbers
set ruler " Show cursor position
set showcmd " Show command in bottom bar
set wildmenu " Visual autocomplete for command menu
set showmatch " Highlight matching brackets
set cursorline " Highlight current line
set laststatus=2 " Always show status line
set colorcolumn=80,120 " Show column markers
" Search Settings
set incsearch " Search as characters are entered
set hlsearch " Highlight search results
set ignorecase " Case insensitive search
set smartcase " Case sensitive when uppercase present
" Indentation
set autoindent " Auto-indent new lines
set smartindent " Smart indent
set expandtab " Use spaces instead of tabs
set tabstop=2 " Number of visual spaces per TAB
set shiftwidth=2 " Number of spaces for auto-indent
set softtabstop=2 " Number of spaces in tab when editing
" Performance
set lazyredraw " Don't redraw while executing macros
set ttyfast " Fast terminal connection
" Backups and Undo
set nobackup " No backup files
set nowritebackup " No backup while editing
set noswapfile " No swap files
set undofile " Persistent undo
set undodir=~/.vim/undo " Undo directory
set undolevels=1000 " Maximum number of undos
set undoreload=10000 " Maximum lines to save for undo
" File Handling
set encoding=utf-8 " Use UTF-8 encoding
set fileencoding=utf-8 " File encoding
set autoread " Auto-reload changed files
set hidden " Allow hidden buffers
" Navigation
set scrolloff=8 " Keep 8 lines above/below cursor
set sidescrolloff=8 " Keep 8 columns left/right of cursor
set mouse=a " Enable mouse support
" Folding
set foldmethod=indent " Fold based on indentation
set foldlevel=99 " Open all folds by default
" Status Line
set statusline=%F " Full file path
set statusline+=%m " Modified flag
set statusline+=%r " Read-only flag
set statusline+=%h " Help buffer flag
set statusline+=%w " Preview window flag
set statusline+=%= " Right align
set statusline+=%y " File type
set statusline+=\ [%{&ff}] " File format
set statusline+=\ [%{strlen(&fenc)?&fenc:'none'}] " File encoding
set statusline+=\ %l:%c " Line:Column
set statusline+=\ %p%% " Percentage through file
" Key Mappings
let mapleader = "," " Set leader key to comma
" Quick save
nnoremap <leader>w :w<CR>
" Quick quit
nnoremap <leader>q :q<CR>
" Clear search highlighting
nnoremap <leader><space> :nohlsearch<CR>
" Split navigation
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" Tab navigation
nnoremap <leader>tn :tabnew<CR>
nnoremap <leader>tc :tabclose<CR>
nnoremap <leader>1 1gt
nnoremap <leader>2 2gt
nnoremap <leader>3 3gt
nnoremap <leader>4 4gt
nnoremap <leader>5 5gt
" Buffer navigation
nnoremap <leader>bn :bnext<CR>
nnoremap <leader>bp :bprevious<CR>
nnoremap <leader>bd :bdelete<CR>
" Paste toggle
set pastetoggle=<F2>
" File Type Specific
autocmd FileType python setlocal tabstop=4 shiftwidth=4 softtabstop=4
autocmd FileType javascript,typescript,json setlocal tabstop=2 shiftwidth=2 softtabstop=2
autocmd FileType yaml,yml setlocal tabstop=2 shiftwidth=2 softtabstop=2
autocmd FileType go setlocal tabstop=4 shiftwidth=4 softtabstop=4 noexpandtab
autocmd FileType markdown setlocal wrap linebreak nolist
" Auto-create undo directory
if !isdirectory($HOME."/.vim/undo")
call mkdir($HOME."/.vim/undo", "p", 0700)
endif
" Colors
set background=dark
if &term =~ "xterm" || &term =~ "screen"
set t_Co=256
endif
" Highlight trailing whitespace
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
" Remember cursor position
autocmd BufReadPost *
\ if line("'\"") > 1 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif