Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions docs/past-failures.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
- Cause: detection treated executable presence as enough, while OpenClaw's ACPX target needs `openclaw acp` to run as a clean stdio ACP server from the daemon environment.
- Mitigation: OpenClaw detection now probes every `openclaw` executable directory on `PATH` with ACPX `sessions ensure`, persists the first PATH ordering that initializes successfully, and omits OpenClaw if none can start ACP. A regression test covers a broken wrapper before a working executable.

## 2026-05-13: Installer service PATH could be truncated by spaces

- Symptom: a node installed successfully, but the user service could later run with a truncated `PATH` when the shell PATH contained entries with spaces such as WSL-mounted `Program Files` directories.
- Cause: the installer wrote raw `Environment=PATH=...` lines into the systemd unit. systemd splits unquoted environment assignments on whitespace.
- Mitigation: the installer now quotes and escapes systemd `Environment` values, and the stdin installer test covers a PATH entry containing spaces.

## 2026-05-12: Installer rejected valid Node 24 runtimes

- Symptom: remote bootstrap failed early with `could not determine Node.js major version` even though `node -v` reported `v24.13.1`.
Expand Down
24 changes: 19 additions & 5 deletions install-amesh-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,16 @@ require_node_major() {
fi
}

systemd_escape_env_value() {
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
}

write_systemd_env() {
key="$1"
value="$2"
printf 'Environment="%s=%s"\n' "$key" "$(systemd_escape_env_value "$value")"
}

main() {
need_cmd curl
need_cmd uname
Expand Down Expand Up @@ -268,24 +278,28 @@ main() {
fail "REGISTRATION_TOKEN is required for first-time registration"
fi

cat >"$SERVICE_PATH" <<EOF
{
cat <<EOF
[Unit]
Description=amesh remote node daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Environment=AMESH_ACPX_PATH=$ACPX_BIN
Environment=AMESH_NODE_VERSION=$tag
Environment=PATH=$PATH
ExecStart=$binary_path run --state $STATE_PATH
EOF
write_systemd_env "AMESH_ACPX_PATH" "$ACPX_BIN"
write_systemd_env "AMESH_NODE_VERSION" "$tag"
write_systemd_env "PATH" "$PATH"
printf 'ExecStart=%q run --state %q\n' "$binary_path" "$STATE_PATH"
cat <<EOF
Restart=always
RestartSec=5

[Install]
WantedBy=default.target
EOF
} >"$SERVICE_PATH"

if command -v systemctl >/dev/null 2>&1; then
systemctl --user daemon-reload
Expand Down
8 changes: 7 additions & 1 deletion scripts/test-install-amesh-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,14 @@ EOF
chmod +x "$stdin_stub_dir/node"

stdin_env_dir="$tmp_dir/stdin-env"
stdin_space_dir="$tmp_dir/stdin path with spaces"
mkdir -p "$stdin_env_dir"
mkdir -p "$stdin_space_dir"
printf '{}\n' >"$stdin_env_dir/agents.json"
printf '{}\n' >"$stdin_env_dir/node-state.json"

stdin_log="$tmp_dir/stdin.log"
if ! PATH="$stdin_stub_dir:$PATH" \
if ! PATH="$stdin_stub_dir:$stdin_space_dir:$PATH" \
AMESH_VERSION_TAG='test-tag' \
INSTALL_DIR="$stdin_env_dir/bin" \
AMESH_HOME="$stdin_env_dir/home" \
Expand All @@ -160,3 +162,7 @@ if ! PATH="$stdin_stub_dir:$PATH" \
cat "$stdin_log" >&2
exit 1
fi

assert_contains 'Environment="AMESH_ACPX_PATH=' "$stdin_env_dir/amesh-node.service"
assert_contains 'Environment="AMESH_NODE_VERSION=test-tag"' "$stdin_env_dir/amesh-node.service"
assert_contains "$stdin_space_dir" "$stdin_env_dir/amesh-node.service"
Loading