You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
14 KiB
459 lines
14 KiB
#!/bin/bash |
|
|
|
############################################################################### |
|
# OpenClaw System Deployment & Management Script |
|
# |
|
# Features: |
|
# - One-click deployment of OpenClaw with systemd services |
|
# - Auto-healing configuration |
|
# - Health monitoring |
|
# - Rollback support via git |
|
# - Telegram notifications |
|
# |
|
# Usage: |
|
# ./deploy.sh install - Install and start all services |
|
# ./deploy.sh start - Start all services |
|
# ./deploy.sh stop - Stop all services |
|
# ./deploy.sh restart - Restart all services |
|
# ./deploy.sh status - Show service status |
|
# ./deploy.sh logs - Show recent logs |
|
# ./deploy.sh health - Run health check |
|
# ./deploy.sh rollback - Rollback to previous git commit |
|
# ./deploy.sh backup - Create backup of current state |
|
# ./deploy.sh debug-stop - Stop ALL services (including monitor) for debugging |
|
# ./deploy.sh debug-start - Start ALL services after debugging |
|
# ./deploy.sh fix-service - Re-inject EnvironmentFile= after OpenClaw UI upgrade |
|
############################################################################### |
|
|
|
set -e |
|
|
|
WORKSPACE="/root/.openclaw/workspace" |
|
LOG_DIR="/root/.openclaw/workspace/logs/system" |
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S) |
|
|
|
# Colors for output |
|
RED='\033[0;31m' |
|
GREEN='\033[0;32m' |
|
YELLOW='\033[1;33m' |
|
BLUE='\033[0;34m' |
|
NC='\033[0m' # No Color |
|
|
|
log_info() { |
|
echo -e "${BLUE}[INFO]${NC} $1" |
|
} |
|
|
|
log_success() { |
|
echo -e "${GREEN}[SUCCESS]${NC} $1" |
|
} |
|
|
|
log_warning() { |
|
echo -e "${YELLOW}[WARNING]${NC} $1" |
|
} |
|
|
|
log_error() { |
|
echo -e "${RED}[ERROR]${NC} $1" |
|
} |
|
|
|
ensure_log_dir() { |
|
mkdir -p "$LOG_DIR" |
|
} |
|
|
|
install_services() { |
|
log_info "Installing OpenClaw systemd services..." |
|
|
|
# Step 1: Enable linger for user-level systemd (CRITICAL for VPS/server deployments) |
|
log_info "Enabling user linger for persistent user-level services..." |
|
loginctl enable-linger $(whoami) |
|
|
|
# Step 2: Export required environment variables |
|
setup_user_env |
|
|
|
if [ ! -d "$XDG_RUNTIME_DIR" ]; then |
|
log_error "XDG_RUNTIME_DIR not found: $XDG_RUNTIME_DIR" |
|
log_warning "Creating runtime directory..." |
|
mkdir -p "$XDG_RUNTIME_DIR" |
|
chmod 700 "$XDG_RUNTIME_DIR" |
|
fi |
|
|
|
# Step 3: Install user-level gateway services |
|
log_info "Installing user-level gateway services..." |
|
mkdir -p ~/.config/systemd/user/ |
|
cp "$WORKSPACE/systemd/openclaw-gateway-user.service" ~/.config/systemd/user/openclaw-gateway.service |
|
cp "$WORKSPACE/systemd/agent-life.service" ~/.config/systemd/user/openclaw-gateway-life.service |
|
|
|
systemctl --user daemon-reload |
|
systemctl --user enable openclaw-gateway |
|
systemctl --user enable openclaw-gateway-life |
|
|
|
# Step 4: Install system-level agent monitor |
|
log_info "Installing system-level agent monitor..." |
|
cp "$WORKSPACE/systemd/openclaw-agent-monitor.service" /etc/systemd/system/ |
|
systemctl daemon-reload |
|
systemctl enable openclaw-agent-monitor |
|
|
|
# Step 5: Inject EnvironmentFile references |
|
fix_service_files |
|
|
|
# Step 6: Start services |
|
log_info "Starting services..." |
|
systemctl --user start openclaw-gateway |
|
systemctl --user start openclaw-gateway-life |
|
systemctl start openclaw-agent-monitor |
|
|
|
sleep 3 |
|
|
|
log_success "OpenClaw services installed and started!" |
|
log_info "Gateway: ws://localhost:18789" |
|
log_info "Life Agent: openclaw-gateway-life.service" |
|
log_info "User service logs: journalctl --user -u openclaw-gateway -f" |
|
log_info "Life agent logs: journalctl --user -u openclaw-gateway-life -f" |
|
log_info "Monitor logs: journalctl -u openclaw-agent-monitor -f" |
|
} |
|
|
|
setup_user_env() { |
|
export XDG_RUNTIME_DIR=/run/user/$(id -u) |
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus" |
|
} |
|
|
|
start_services() { |
|
log_info "Starting OpenClaw services..." |
|
setup_user_env |
|
|
|
systemctl --user start openclaw-gateway |
|
systemctl --user start openclaw-gateway-life |
|
systemctl start openclaw-agent-monitor |
|
log_success "All services started (gateway + life + monitor)" |
|
} |
|
|
|
stop_services() { |
|
log_info "Stopping OpenClaw services..." |
|
setup_user_env |
|
|
|
systemctl --user stop openclaw-gateway |
|
systemctl --user stop openclaw-gateway-life |
|
systemctl stop openclaw-agent-monitor |
|
log_success "All services stopped" |
|
} |
|
|
|
restart_services() { |
|
log_info "Restarting OpenClaw services..." |
|
setup_user_env |
|
|
|
systemctl --user restart openclaw-gateway |
|
systemctl --user restart openclaw-gateway-life |
|
systemctl restart openclaw-agent-monitor |
|
log_success "All services restarted (gateway + life + monitor)" |
|
} |
|
|
|
debug_stop() { |
|
log_warning "=== DEBUG MODE: Stopping ALL services ===" |
|
log_warning "Monitor will NOT auto-restart gateway while in debug mode." |
|
log_warning "Run './deploy.sh debug-start' when done debugging." |
|
setup_user_env |
|
|
|
systemctl stop openclaw-agent-monitor 2>/dev/null || true |
|
systemctl --user stop openclaw-gateway 2>/dev/null || true |
|
systemctl --user stop openclaw-gateway-life 2>/dev/null || true |
|
|
|
log_success "All services stopped. Safe to debug." |
|
echo "" |
|
log_info "Useful debug commands:" |
|
log_info " openclaw gateway start # start gateway in foreground" |
|
log_info " journalctl --user -u openclaw-gateway -n 100" |
|
log_info " journalctl --user -u openclaw-gateway-life -n 100" |
|
} |
|
|
|
debug_start() { |
|
log_info "=== Exiting DEBUG MODE: Restarting ALL services ===" |
|
setup_user_env |
|
|
|
systemctl --user start openclaw-gateway |
|
systemctl --user start openclaw-gateway-life |
|
systemctl start openclaw-agent-monitor |
|
|
|
sleep 2 |
|
log_success "All services restored. Monitor is active again." |
|
health_check |
|
} |
|
|
|
fix_service_files() { |
|
log_info "Ensuring EnvironmentFile= is present in installed service files..." |
|
setup_user_env |
|
|
|
local gateway_svc="$HOME/.config/systemd/user/openclaw-gateway.service" |
|
local life_svc="$HOME/.config/systemd/user/openclaw-gateway-life.service" |
|
local gateway_env="$WORKSPACE/systemd/gateway.env" |
|
local life_env="$WORKSPACE/systemd/life-gateway.env" |
|
local changed=0 |
|
|
|
if [ -f "$gateway_svc" ]; then |
|
if ! grep -q "EnvironmentFile=.*gateway.env" "$gateway_svc" 2>/dev/null; then |
|
sed -i "/^\[Service\]/a EnvironmentFile=-${gateway_env}" "$gateway_svc" |
|
log_info "Injected EnvironmentFile into openclaw-gateway.service" |
|
changed=1 |
|
else |
|
log_info "openclaw-gateway.service already has EnvironmentFile" |
|
fi |
|
fi |
|
|
|
if [ -f "$life_svc" ]; then |
|
if ! grep -q "EnvironmentFile=.*life-gateway.env" "$life_svc" 2>/dev/null; then |
|
sed -i "/^\[Service\]/a EnvironmentFile=-${life_env}" "$life_svc" |
|
log_info "Injected EnvironmentFile into openclaw-gateway-life.service" |
|
changed=1 |
|
else |
|
log_info "openclaw-gateway-life.service already has EnvironmentFile" |
|
fi |
|
fi |
|
|
|
if [ $changed -eq 1 ]; then |
|
systemctl --user daemon-reload |
|
log_success "Service files updated. Run './deploy.sh restart' to apply." |
|
else |
|
log_success "All service files are up to date." |
|
fi |
|
} |
|
|
|
show_status() { |
|
setup_user_env |
|
|
|
echo "" |
|
log_info "=== OpenClaw Gateway (User Service) ===" |
|
systemctl --user status openclaw-gateway --no-pager -l 2>&1 || true |
|
echo "" |
|
log_info "=== Life Agent (User Service) ===" |
|
systemctl --user status openclaw-gateway-life --no-pager -l 2>&1 || true |
|
echo "" |
|
log_info "=== Agent Monitor (System Service) ===" |
|
systemctl status openclaw-agent-monitor --no-pager -l 2>&1 || true |
|
echo "" |
|
log_info "=== Recent Gateway Logs ===" |
|
journalctl --user -u openclaw-gateway --no-pager -n 10 |
|
echo "" |
|
log_info "=== Recent Life Agent Logs ===" |
|
journalctl --user -u openclaw-gateway-life --no-pager -n 10 |
|
echo "" |
|
log_info "=== Recent Monitor Logs ===" |
|
journalctl -u openclaw-agent-monitor --no-pager -n 10 |
|
} |
|
|
|
show_logs() { |
|
setup_user_env |
|
|
|
log_info "Showing recent gateway logs (last 50 lines)..." |
|
journalctl --user -u openclaw-gateway --no-pager -n 50 |
|
echo "" |
|
log_info "Showing recent life agent logs (last 50 lines)..." |
|
journalctl --user -u openclaw-gateway-life --no-pager -n 50 |
|
echo "" |
|
log_info "Showing recent monitor logs (last 50 lines)..." |
|
journalctl -u openclaw-agent-monitor --no-pager -n 50 |
|
} |
|
|
|
rollback() { |
|
log_warning "This will rollback the workspace to the previous git commit!" |
|
read -p "Are you sure? (y/N): " confirm |
|
|
|
if [[ $confirm =~ ^[Yy]$ ]]; then |
|
cd "$WORKSPACE" |
|
|
|
# Create backup before rollback |
|
backup |
|
|
|
# Show current commit |
|
log_info "Current commit:" |
|
git log -1 --oneline |
|
|
|
# Rollback |
|
git reset --hard HEAD~1 |
|
|
|
log_success "Rolled back to previous commit!" |
|
log_info "Restarting services to apply changes..." |
|
restart_services |
|
else |
|
log_info "Rollback cancelled." |
|
fi |
|
} |
|
|
|
rollback_to() { |
|
if [ -z "$1" ]; then |
|
log_error "Please specify a commit hash or tag" |
|
exit 1 |
|
fi |
|
|
|
log_warning "This will rollback the workspace to commit: $1" |
|
read -p "Are you sure? (y/N): " confirm |
|
|
|
if [[ $confirm =~ ^[Yy]$ ]]; then |
|
cd "$WORKSPACE" |
|
backup |
|
git reset --hard "$1" |
|
log_success "Rolled back to commit: $1" |
|
restart_services |
|
else |
|
log_info "Rollback cancelled." |
|
fi |
|
} |
|
|
|
backup() { |
|
local backup_dir="/root/.openclaw/backups" |
|
mkdir -p "$backup_dir" |
|
|
|
log_info "Creating backup..." |
|
|
|
# Backup workspace |
|
tar -czf "$backup_dir/workspace-$TIMESTAMP.tar.gz" \ |
|
--exclude='.git' \ |
|
--exclude='logs' \ |
|
-C /root/.openclaw workspace |
|
|
|
# Backup config |
|
cp /root/.openclaw/openclaw.json "$backup_dir/openclaw-config-$TIMESTAMP.json" 2>/dev/null || true |
|
|
|
log_success "Backup created: $backup_dir/workspace-$TIMESTAMP.tar.gz" |
|
} |
|
|
|
health_check() { |
|
log_info "Running health check..." |
|
setup_user_env |
|
|
|
local issues=0 |
|
|
|
if systemctl --user is-active --quiet openclaw-gateway 2>/dev/null; then |
|
log_success "✓ Gateway is running" |
|
else |
|
log_error "✗ Gateway is not running" |
|
((issues++)) |
|
fi |
|
|
|
if systemctl --user is-active --quiet openclaw-gateway-life 2>/dev/null; then |
|
log_success "✓ Life Agent is running" |
|
else |
|
log_error "✗ Life Agent is not running" |
|
((issues++)) |
|
fi |
|
|
|
if systemctl is-active --quiet openclaw-agent-monitor; then |
|
log_success "✓ Agent Monitor is running" |
|
else |
|
log_error "✗ Agent Monitor is not running" |
|
((issues++)) |
|
fi |
|
|
|
# Check disk space |
|
local disk_usage=$(df -h /root | tail -1 | awk '{print $5}' | sed 's/%//') |
|
if [ "$disk_usage" -lt 80 ]; then |
|
log_success "✓ Disk usage: ${disk_usage}%" |
|
else |
|
log_warning "⚠ Disk usage: ${disk_usage}%" |
|
((issues++)) |
|
fi |
|
|
|
# Check memory |
|
local mem_usage=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100.0)}') |
|
if [ "$mem_usage" -lt 80 ]; then |
|
log_success "✓ Memory usage: ${mem_usage}%" |
|
else |
|
log_warning "⚠ Memory usage: ${mem_usage}%" |
|
((issues++)) |
|
fi |
|
|
|
# Check XDG_RUNTIME_DIR |
|
if [ -d "$XDG_RUNTIME_DIR" ]; then |
|
log_success "✓ XDG_RUNTIME_DIR exists: $XDG_RUNTIME_DIR" |
|
else |
|
log_warning "⚠ XDG_RUNTIME_DIR not found" |
|
((issues++)) |
|
fi |
|
|
|
# Check linger status |
|
if loginctl show-user $(whoami) -p Linger | grep -q "yes"; then |
|
log_success "✓ User linger is enabled" |
|
else |
|
log_warning "⚠ User linger is NOT enabled (run: loginctl enable-linger)" |
|
((issues++)) |
|
fi |
|
|
|
echo "" |
|
if [ $issues -eq 0 ]; then |
|
log_success "All health checks passed!" |
|
return 0 |
|
else |
|
log_error "$issues health check(s) failed!" |
|
return 1 |
|
fi |
|
} |
|
|
|
show_help() { |
|
echo "OpenClaw System Management Script" |
|
echo "" |
|
echo "Usage: $0 <command>" |
|
echo "" |
|
echo "Commands:" |
|
echo " install - Install and start all systemd services" |
|
echo " start - Start all services (gateway + life + monitor)" |
|
echo " stop - Stop all services" |
|
echo " restart - Restart all services" |
|
echo " status - Show service status" |
|
echo " logs - Show recent logs" |
|
echo " health - Run health check" |
|
echo " backup - Create backup of current state" |
|
echo " rollback - Rollback to previous git commit" |
|
echo " rollback-to - Rollback to specific commit" |
|
echo " debug-stop - Stop ALL services including monitor (safe for debugging)" |
|
echo " debug-start - Restart all services after debugging" |
|
echo " fix-service - Re-inject EnvironmentFile after OpenClaw UI upgrade" |
|
echo " help - Show this help message" |
|
echo "" |
|
} |
|
|
|
# Main |
|
case "${1:-help}" in |
|
install) |
|
install_services |
|
;; |
|
start) |
|
start_services |
|
;; |
|
stop) |
|
stop_services |
|
;; |
|
restart) |
|
restart_services |
|
;; |
|
status) |
|
show_status |
|
;; |
|
logs) |
|
show_logs |
|
;; |
|
health) |
|
health_check |
|
;; |
|
backup) |
|
backup |
|
;; |
|
rollback) |
|
rollback |
|
;; |
|
rollback-to) |
|
rollback_to "$2" |
|
;; |
|
debug-stop) |
|
debug_stop |
|
;; |
|
debug-start) |
|
debug_start |
|
;; |
|
fix-service) |
|
fix_service_files |
|
;; |
|
help|--help|-h) |
|
show_help |
|
;; |
|
*) |
|
log_error "Unknown command: $1" |
|
show_help |
|
exit 1 |
|
;; |
|
esac
|
|
|