|
|
|
|
#!/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 rollback - Rollback to previous git commit
|
|
|
|
|
# ./deploy.sh backup - Create backup of current state
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
# Verify environment
|
|
|
|
|
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 service
|
|
|
|
|
log_info "Installing user-level gateway service..."
|
|
|
|
|
mkdir -p ~/.config/systemd/user/
|
|
|
|
|
cp "$WORKSPACE/systemd/openclaw-gateway-user.service" ~/.config/systemd/user/openclaw-gateway.service
|
|
|
|
|
|
|
|
|
|
# Reload user systemd daemon
|
|
|
|
|
systemctl --user daemon-reload
|
|
|
|
|
systemctl --user enable openclaw-gateway
|
|
|
|
|
|
|
|
|
|
# Step 4: Install system-level agent monitor (independent of user session)
|
|
|
|
|
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: Start services
|
|
|
|
|
log_info "Starting services..."
|
|
|
|
|
systemctl --user start openclaw-gateway
|
|
|
|
|
systemctl start openclaw-agent-monitor
|
|
|
|
|
|
|
|
|
|
# Wait for gateway to be ready
|
|
|
|
|
sleep 3
|
|
|
|
|
|
|
|
|
|
log_success "OpenClaw services installed and started!"
|
|
|
|
|
log_info "Gateway: ws://localhost:18789"
|
|
|
|
|
log_info "Dashboard: http://localhost:18789/"
|
|
|
|
|
log_info "User service logs: journalctl --user -u openclaw-gateway -f"
|
|
|
|
|
log_info "Monitor logs: journalctl -u openclaw-agent-monitor -f"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start_services() {
|
|
|
|
|
log_info "Starting OpenClaw services..."
|
|
|
|
|
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
systemctl --user start openclaw-gateway
|
|
|
|
|
systemctl start openclaw-agent-monitor
|
|
|
|
|
log_success "Services started!"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stop_services() {
|
|
|
|
|
log_info "Stopping OpenClaw services..."
|
|
|
|
|
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
systemctl --user stop openclaw-gateway
|
|
|
|
|
systemctl stop openclaw-agent-monitor
|
|
|
|
|
log_success "Services stopped!"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restart_services() {
|
|
|
|
|
log_info "Restarting OpenClaw services..."
|
|
|
|
|
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
systemctl --user restart openclaw-gateway
|
|
|
|
|
systemctl restart openclaw-agent-monitor
|
|
|
|
|
log_success "Services restarted!"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
show_status() {
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
log_info "=== OpenClaw Gateway Status (User Service) ==="
|
|
|
|
|
systemctl --user status openclaw-gateway --no-pager -l
|
|
|
|
|
echo ""
|
|
|
|
|
log_info "=== Agent Monitor Status (System Service) ==="
|
|
|
|
|
systemctl status openclaw-agent-monitor --no-pager -l
|
|
|
|
|
echo ""
|
|
|
|
|
log_info "=== Recent Gateway Logs ==="
|
|
|
|
|
journalctl --user -u openclaw-gateway --no-pager -n 15
|
|
|
|
|
echo ""
|
|
|
|
|
log_info "=== Recent Monitor Logs ==="
|
|
|
|
|
journalctl -u openclaw-agent-monitor --no-pager -n 15
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
show_logs() {
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
log_info "Showing recent gateway logs (last 50 lines)..."
|
|
|
|
|
journalctl --user -u openclaw-gateway --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..."
|
|
|
|
|
|
|
|
|
|
# Set up environment for user-level services
|
|
|
|
|
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
|
|
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"
|
|
|
|
|
|
|
|
|
|
local issues=0
|
|
|
|
|
|
|
|
|
|
# Check gateway (user-level service)
|
|
|
|
|
if systemctl --user is-active --quiet openclaw-gateway 2>/dev/null; then
|
|
|
|
|
log_success "✓ Gateway is running (user service)"
|
|
|
|
|
else
|
|
|
|
|
log_error "✗ Gateway is not running"
|
|
|
|
|
((issues++))
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Check monitor (system-level service)
|
|
|
|
|
if systemctl is-active --quiet openclaw-agent-monitor; then
|
|
|
|
|
log_success "✓ Agent Monitor is running (system service)"
|
|
|
|
|
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"
|
|
|
|
|
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 <commit> - Rollback to specific commit"
|
|
|
|
|
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"
|
|
|
|
|
;;
|
|
|
|
|
help|--help|-h)
|
|
|
|
|
show_help
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
log_error "Unknown command: $1"
|
|
|
|
|
show_help
|
|
|
|
|
exit 1
|
|
|
|
|
;;
|
|
|
|
|
esac
|