From 9cc81d5e47a45ec7bd489dbda2c47b17f09c17a7 Mon Sep 17 00:00:00 2001 From: Nitay Rabinovich Date: Wed, 13 May 2026 20:49:31 +0200 Subject: [PATCH] quote systemd service environment --- docs/past-failures.md | 6 ++++++ install-amesh-node.sh | 24 +++++++++++++++++++----- scripts/test-install-amesh-node.sh | 8 +++++++- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/past-failures.md b/docs/past-failures.md index 15debb0..0eefd8b 100644 --- a/docs/past-failures.md +++ b/docs/past-failures.md @@ -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`. diff --git a/install-amesh-node.sh b/install-amesh-node.sh index 34d8880..261dc2f 100644 --- a/install-amesh-node.sh +++ b/install-amesh-node.sh @@ -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 @@ -268,7 +278,8 @@ main() { fail "REGISTRATION_TOKEN is required for first-time registration" fi - cat >"$SERVICE_PATH" <"$SERVICE_PATH" if command -v systemctl >/dev/null 2>&1; then systemctl --user daemon-reload diff --git a/scripts/test-install-amesh-node.sh b/scripts/test-install-amesh-node.sh index cf3f8d3..08bfeed 100644 --- a/scripts/test-install-amesh-node.sh +++ b/scripts/test-install-amesh-node.sh @@ -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" \ @@ -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"