diff --git a/bin/omarchy-install-openclaw-cli b/bin/omarchy-install-openclaw-cli index 83948199..e3578d53 100755 --- a/bin/omarchy-install-openclaw-cli +++ b/bin/omarchy-install-openclaw-cli @@ -122,15 +122,20 @@ stop_legacy_services() { done } -# Not moved yet: still on the old copy, run by a Node outside the runtime, or -# running before and not now. Upstream's installer keeps the Node a service -# already had, so a moved unit can run the runtime's code on the system Node -# the old package depended on, which this one no longer does. +# Still the old package's: its script, or the runtime's script on the old +# package's Node. Upstream's installer keeps the Node a service already ran, so +# a moved unit can end up running ~/.openclaw on /usr/bin/node, from the nodejs +# package the seed no longer depends on. Any other Node or Bun is the user's. +on_old_package() { + local program + program=$(sed -n 's/^ExecStart=//p' "$1" | head -1) + program=${program%% *} + unit_runs "$1" "/usr/lib/node_modules/openclaw/" || { [[ $program == "/usr/bin/node" ]] && unit_runs "$1" "$prefix/"; } +} + +# Not moved yet: still on the old package, or running before and not now. unsettled() { - local unit words - unit=$(unit_path "$1") - read -ra words <<<"$(sed -n 's/^ExecStart=//p' "$unit" | head -1)" - unit_runs "$unit" "/usr/lib/node_modules/openclaw/" || [[ ${words[0]:-} != "$prefix/"* ]] || + on_old_package "$(unit_path "$1")" || { [[ " ${running[*]} " == *" $1 "* ]] && ! systemctl --user is-active --quiet "openclaw-$1.service"; } } @@ -214,7 +219,7 @@ moving=() running=() stopped=() for role in gateway node; do - if [[ -f $(unit_path "$role") ]] && unit_runs "$(unit_path "$role")" "/usr/lib/node_modules/openclaw/"; then + if [[ -f $(unit_path "$role") ]] && on_old_package "$(unit_path "$role")"; then moving+=("$role") if systemctl --user is-active --quiet "openclaw-$role.service"; then running+=("$role") diff --git a/test/shell.d/openclaw-cli-test.sh b/test/shell.d/openclaw-cli-test.sh index d7e6625d..d629ee27 100755 --- a/test/shell.d/openclaw-cli-test.sh +++ b/test/shell.d/openclaw-cli-test.sh @@ -249,6 +249,36 @@ run omarchy-install-openclaw-cli --now || fail "--now moves a gateway beside a r fail "--now moves a gateway beside a runtime that already runs" "$(cat "$events")" pass "a gateway beside a runtime that already runs is moved without seeding" +# A move that stopped halfway left the runtime's code on the old package's +# /usr/bin/node; the next run finishes it, and moves a node host the same way. +new_home half-moved +run omarchy-install-openclaw-cli --now || fail "--now sets OpenClaw up" "$(cat "$test_tmp/output")" +mkdir -p "$test_home/.config/systemd/user" +printf 'ExecStart=/usr/bin/node %s/.openclaw/tools/node-v24.19.0/lib/node_modules/openclaw/dist/index.js gateway --port 18789\n' "$test_home" >"$test_home/.config/systemd/user/openclaw-gateway.service" +printf 'ExecStart=/usr/bin/node /usr/lib/node_modules/openclaw/dist/index.js node run\n' >"$test_home/.config/systemd/user/openclaw-node.service" +touch "$test_home/active-openclaw-gateway.service" "$test_home/active-openclaw-node.service" +: >"$events" +run omarchy-install-openclaw-cli --now || fail "--now finishes a half-moved gateway" "$(cat "$test_tmp/output")" +for role in gateway node; do + grep -Fxq "runtime $role install --force --runtime-path $test_home/.openclaw/tools/node-v24.19.0/bin/node" "$events" && + sed -n 's/^ExecStart=\([^ ]*\).*/\1/p' "$test_home/.config/systemd/user/openclaw-$role.service" | grep -qx "$test_home/.openclaw/tools/node-v24.19.0/bin/node" || + fail "--now finishes a half-moved $role on the runtime's own Node" "$(cat "$events")" +done +pass "a half-moved gateway and a node host end up on the runtime's own Node" + +# The runtime run by any other Node or by Bun is the user's choice, not the old +# package's dependency. +new_home bun +run omarchy-install-openclaw-cli --now || fail "--now sets OpenClaw up" "$(cat "$test_tmp/output")" +mkdir -p "$test_home/.config/systemd/user" +printf 'ExecStart=/usr/bin/bun %s/.openclaw/tools/node-v24.19.0/lib/node_modules/openclaw/dist/index.js gateway --port 18789\n' "$test_home" >"$test_home/.config/systemd/user/openclaw-gateway.service" +cp "$test_home/.config/systemd/user/openclaw-gateway.service" "$test_tmp/bun-unit" +: >"$events" +run omarchy-install-openclaw-cli --now || fail "--now leaves a Bun gateway alone" "$(cat "$test_tmp/output")" +! grep -q "install --force\|^systemctl" "$events" && cmp -s "$test_tmp/bun-unit" "$test_home/.config/systemd/user/openclaw-gateway.service" || + fail "--now leaves a Bun gateway alone" "$(cat "$events")" +pass "a gateway the user runs on Bun is left alone" + # The migration moves only machines that have the package, and waits for the # package that seeds. new_home migration-none