Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ remove_file_with_optional_sudo() {
info "Removed $path"
}

# Stop NemoClaw helper services (e.g. Telegram bridge, cloudflared).
stop_helper_services() {
if [ -x "$SCRIPT_DIR/scripts/start-services.sh" ]; then
run_optional "Stopped NemoClaw helper services" "$SCRIPT_DIR/scripts/start-services.sh" --stop
Expand All @@ -251,6 +252,7 @@ stop_helper_services() {
remove_glob_paths "${TMP_ROOT}/nemoclaw-services-*"
}

# Stop openshell port-forward processes on the dashboard port.
stop_openshell_forward_processes() {
if ! command -v pgrep >/dev/null 2>&1; then
warn "pgrep not found; skipping local OpenShell forward process cleanup."
Expand Down Expand Up @@ -281,6 +283,71 @@ stop_openshell_forward_processes() {
done
}

# Kill orphaned openshell processes left behind after uninstall —
# sandbox create, ssh-proxy, and related ssh sessions. (#1940)
stop_orphaned_openshell_processes() {
if ! command -v pgrep >/dev/null 2>&1; then
warn "pgrep not found; skipping orphaned openshell process cleanup."
return 0
fi

local -a pids=()
local pid

# Scope to the original invoking user to avoid killing other users' processes
# on shared systems. Under sudo, SUDO_USER holds the real caller; fall back
# to LOGNAME, then id -un. (#1940)
local _user
_user="${SUDO_USER:-${LOGNAME:-$(id -un 2>/dev/null || echo "")}}"
local -a _pgrep_user=()
if [ -n "$_user" ]; then
_pgrep_user=(-u "$_user")
fi

# Collect openshell sandbox create, ssh-proxy, and related ssh processes.
while IFS= read -r pid; do
[ -n "$pid" ] || continue
pids+=("$pid")
done < <(pgrep "${_pgrep_user[@]}" -f "openshell (sandbox create|ssh-proxy)" 2>/dev/null || true)

# Also collect ssh processes whose command line references openshell.
# Match "openshell ssh-proxy" or "openshell-" (gateway name pattern) to
# avoid false positives on unrelated ssh sessions. User scoping via
# _pgrep_user provides an additional safety net.
local cmd
while IFS= read -r pid; do
[ -n "$pid" ] || continue
cmd="$(ps -p "$pid" -o args= 2>/dev/null)" || continue
if [[ "$cmd" == *"openshell ssh-proxy"* ]] || [[ "$cmd" == *"openshell-"* ]]; then
pids+=("$pid")
fi
done < <(pgrep "${_pgrep_user[@]}" -x ssh 2>/dev/null || true)

# Deduplicate
local -A seen=()
local -a unique_pids=()
for pid in "${pids[@]}"; do
if [ -z "${seen[$pid]:-}" ]; then
seen[$pid]=1
unique_pids+=("$pid")
fi
done

if [ "${#unique_pids[@]}" -eq 0 ]; then
info "No orphaned openshell processes found"
return 0
fi

for pid in "${unique_pids[@]}"; do
if kill "$pid" >/dev/null 2>&1 || kill -9 "$pid" >/dev/null 2>&1; then
info "Stopped orphaned openshell process $pid"
else
warn "Failed to stop orphaned openshell process $pid"
fi
done
}

# Remove OpenShell sandboxes, providers, and gateway.
remove_openshell_resources() {
if ! command -v openshell >/dev/null 2>&1; then
warn "openshell not found; skipping gateway/provider/sandbox cleanup."
Expand Down Expand Up @@ -629,6 +696,7 @@ main() {
step 1 "Stopping services"
stop_helper_services
stop_openshell_forward_processes
stop_orphaned_openshell_processes

step 2 "OpenShell resources"
remove_openshell_resources
Expand Down
Loading