1+ #! /usr/bin/env bash
2+ #
3+ # OpenClaw Cleanup Script (Linux version)
4+ # Function: Detect and uninstall openclaw packages on Linux
5+ #
6+ # Execution flow:
7+ # 1. Check if Node.js exists → exit if not found
8+ # 2. Check package manager (npm/pnpm)
9+ # 3. Check if openclaw packages exist → exit if not found
10+ # 4. Stop all node processes → exit with error if failed
11+ # 5. Uninstall openclaw packages → exit with success
12+ #
13+
14+ # Silent mode flag
15+ SILENT=false
16+ if [[ " $1 " == " -s" ]] || [[ " $1 " == " --silent" ]]; then
17+ SILENT=true
18+ fi
19+
20+ # Set UTF-8 encoding
21+ export LANG=en_US.UTF-8
22+ export LC_ALL=en_US.UTF-8
23+
24+ # ============================================
25+ # Logging Setup (Must be defined first)
26+ # ============================================
27+ LOG_DIR=" /tmp/openclaw-cleanup"
28+
29+ mkdir -p " $LOG_DIR " 2> /dev/null
30+ LOG_FILE=" $LOG_DIR /Cleanup_$( date +' %Y%m%d_%H%M%S' ) .log"
31+
32+ write_log () {
33+ local message=" $1 "
34+ local level=" ${2:- Info} "
35+ local timestamp=$( date +' %Y-%m-%d %H:%M:%S' )
36+ local log_line=" [$timestamp ] [$level ] $message "
37+ echo " $log_line " >> " $LOG_FILE "
38+ if [ " $SILENT " = false ]; then
39+ case " $level " in
40+ " Success" ) echo -e " \e[32m[SUCCESS] $message \e[0m" ;;
41+ " Error" ) echo -e " \e[31m[ERROR] $message \e[0m" ;;
42+ " Info" ) echo -e " \e[36m[INFO] $message \e[0m" ;;
43+ * ) echo " [$level ] $message " ;;
44+ esac
45+ fi
46+ }
47+
48+ write_log " ========== OpenClaw Cleanup Script (Linux) Started ==========" " Info"
49+
50+ # ============================================
51+ # Environment Setup: Ensure Node.js is in PATH
52+ # ============================================
53+ export PATH=" /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH "
54+
55+ write_log " Searching for Node.js in user directories..." " Info"
56+ for user_home in /home/* ; do
57+ if [ -d " $user_home /.nvm" ]; then
58+ export NVM_DIR=" $user_home /.nvm"
59+ if [ -s " $NVM_DIR /nvm.sh" ]; then
60+ \. " $NVM_DIR /nvm.sh"
61+ write_log " Sourced NVM for user $( basename " $user_home " ) " " Success"
62+ fi
63+ fi
64+ done
65+
66+ if [ -d " $HOME /.nvm" ]; then
67+ export NVM_DIR=" $HOME /.nvm"
68+ [ -s " $NVM_DIR /nvm.sh" ] && \. " $NVM_DIR /nvm.sh"
69+ fi
70+
71+
72+ # ============================================
73+ # Step 1-5: Local Node.js Package Cleanup
74+ # ============================================
75+ cleanup_local_node_packages () {
76+ write_log " Starting local Node.js package cleanup..." " Info"
77+
78+ # --- Check for Node.js ---
79+ if ! command -v node & > /dev/null; then
80+ write_log " Node.js not found, skipping local package cleanup." " Info"
81+ return # Exit function, not script
82+ fi
83+ write_log " Node.js detected, version: $( node --version) " " Success"
84+
85+ # --- Check for package manager ---
86+ package_manager=" "
87+ if command -v pnpm & > /dev/null; then package_manager=" pnpm" ;
88+ elif command -v npm & > /dev/null; then package_manager=" npm" ; fi
89+
90+ if [ -z " $package_manager " ]; then
91+ write_log " Neither npm nor pnpm found, skipping local package cleanup." " Info"
92+ return # Exit function, not script
93+ fi
94+ write_log " Using package manager: $package_manager " " Success"
95+
96+ # --- Check for openclaw packages ---
97+ target_packages=(" openclaw" " openclaw-cn" )
98+ found_packages=()
99+ for pkg in " ${target_packages[@]} " ; do
100+ if [ " $package_manager " = " npm" ] && npm list -g " $pkg " --depth=0 2>&1 | grep -qE " $pkg @[0-9]" ; then
101+ found_packages+=(" $pkg " )
102+ elif [ " $package_manager " = " pnpm" ] && ! pnpm list -g " $pkg " --depth=0 2>&1 | grep -q " No packages found" ; then
103+ found_packages+=(" $pkg " )
104+ fi
105+ done
106+
107+ if [ ${# found_packages[@]} -eq 0 ]; then
108+ write_log " No openclaw packages detected locally." " Info"
109+ return # Exit function, not script
110+ fi
111+ write_log " Found packages to uninstall: ${found_packages[*]} " " Info"
112+
113+ # --- Stop node processes ---
114+ write_log " Stopping node processes..." " Info"
115+ local node_pids=$( pgrep -x node)
116+ if [ -n " $node_pids " ]; then
117+ for pid in $node_pids ; do kill -TERM " $pid " 2> /dev/null; done
118+ sleep 2
119+ for pid in $( pgrep -x node) ; do kill -9 " $pid " 2> /dev/null; done
120+ fi
121+
122+ # --- Uninstall packages ---
123+ SUDO=" "
124+ if [ " $EUID " -ne 0 ] && [ ! -w " $( npm root -g 2> /dev/null) " ]; then SUDO=" sudo" ; fi
125+ for pkg in " ${found_packages[@]} " ; do
126+ write_log " Uninstalling $pkg ..." " Info"
127+ if $SUDO " $package_manager " uninstall -g " $pkg " & > /dev/null; then
128+ write_log " Successfully uninstalled: $pkg " " Success"
129+ else
130+ write_log " Failed to uninstall: $pkg " " Error"
131+ fi
132+ done
133+ }
134+
135+
136+ # ============================================
137+ # Docker Cleanup Function (Multi-User & Rootless Aware)
138+ # ============================================
139+ cleanup_docker () {
140+ write_log " Starting comprehensive Docker cleanup..." " Info"
141+
142+ if ! command -v docker & > /dev/null; then
143+ write_log " Docker command not found, skipping." " Info"
144+ return
145+ fi
146+
147+ # 1. Collect all potential Docker Sockets (System-wide + Rootless)
148+ local sockets=()
149+ [ -S " /var/run/docker.sock" ] && sockets+=(" /var/run/docker.sock" )
150+
151+ # Search for rootless docker sockets
152+ for user_sock in /run/user/* /docker.sock; do
153+ [ -S " $user_sock " ] && sockets+=(" $user_sock " )
154+ done
155+
156+ if [ ${# sockets[@]} -eq 0 ]; then
157+ write_log " No active Docker sockets found." " Info"
158+ return
159+ fi
160+
161+ for sock in " ${sockets[@]} " ; do
162+ write_log " Cleaning Docker instance at $sock ..." " Info"
163+ export DOCKER_HOST=" unix://$sock "
164+
165+ # Find and remove containers
166+ local containers=$( docker ps -a -q --filter " name=openclaw" 2> /dev/null)
167+ if [ -n " $containers " ]; then
168+ docker stop $containers & > /dev/null
169+ docker rm $containers & > /dev/null
170+ write_log " Removed containers at $sock " " Success"
171+ fi
172+
173+ # Find and remove images
174+ local images=$( docker images -q " *openclaw*" 2> /dev/null)
175+ if [ -n " $images " ]; then
176+ docker rmi -f $images & > /dev/null
177+ write_log " Removed images at $sock " " Success"
178+ fi
179+
180+ unset DOCKER_HOST
181+ done
182+ }
183+
184+
185+ # ============================================
186+ # Main Execution
187+ # ============================================
188+ cleanup_local_node_packages
189+ cleanup_docker
190+
191+ write_log " ========== Cleanup Completed ==========" " Success"
192+ exit 0
0 commit comments