fix(scripts): avoid mutating tracked auth-monitor template during setup (#53920)

* fix(scripts): render auth monitor unit before install

Render the auth monitor service into temporary files instead of editing the tracked template. Quote the generated ExecStart safely, including spaces and literal dollars, then atomically install the rendered unit.

* fix(scripts): avoid mutating tracked auth-monitor template during setup

* fix(scripts): avoid mutating tracked auth-monitor template during setup

* fix(scripts): avoid mutating tracked auth-monitor template during setup

---------

Co-authored-by: JackWuGlobal <JackWuGlobal@users.noreply.github.com>
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
This commit is contained in:
JackWu
2026-06-19 08:24:16 +08:00
committed by GitHub
parent 843b1d6fbb
commit e9e44bf83c
3 changed files with 99 additions and 12 deletions

View File

@@ -60,21 +60,88 @@ echo " OpenClaw message: Send warning via OpenClaw itself"
echo "Enter your phone number for alerts (or leave blank to skip):"
read -r PHONE_NUMBER
# Update service file
SERVICE_FILE="$SCRIPT_DIR/systemd/openclaw-auth-monitor.service"
if [ -n "$NTFY_TOPIC" ]; then
sed -i "s|# Environment=NOTIFY_NTFY=.*|Environment=NOTIFY_NTFY=$NTFY_TOPIC|" "$SERVICE_FILE"
fi
if [ -n "$PHONE_NUMBER" ]; then
sed -i "s|# Environment=NOTIFY_PHONE=.*|Environment=NOTIFY_PHONE=$PHONE_NUMBER|" "$SERVICE_FILE"
fi
# Install systemd units
SERVICE_TEMPLATE="$SCRIPT_DIR/systemd/openclaw-auth-monitor.service"
SYSTEMD_USER_DIR="$HOME/.config/systemd/user"
SERVICE_TARGET="$SYSTEMD_USER_DIR/openclaw-auth-monitor.service"
TIMER_TARGET="$SYSTEMD_USER_DIR/openclaw-auth-monitor.timer"
AUTH_MONITOR_PATH="$SCRIPT_DIR/auth-monitor.sh"
echo ""
echo "Installing systemd timer..."
mkdir -p ~/.config/systemd/user
cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.service" ~/.config/systemd/user/
cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.timer" ~/.config/systemd/user/
mkdir -p "$SYSTEMD_USER_DIR"
SERVICE_TEMP="$(mktemp "$SYSTEMD_USER_DIR/openclaw-auth-monitor.service.XXXXXX")"
SERVICE_RENDERED=""
cleanup_service_temp() {
rm -f "$SERVICE_TEMP" "$SERVICE_RENDERED"
}
trap cleanup_service_temp EXIT
SERVICE_RENDERED="$(mktemp "$SYSTEMD_USER_DIR/openclaw-auth-monitor.service.rendered.XXXXXX")"
cp "$SERVICE_TEMPLATE" "$SERVICE_TEMP"
systemd_quote_arg() {
local value="$1"
value="${value//\\/\\\\}"
value="${value//%/%%}"
value="${value//\$/\$\$}"
value="${value//\"/\\\"}"
printf '"%s"' "$value"
}
render_environment_line() {
local key="$1"
local placeholder="$2"
local value="$3"
if [ -n "$value" ]; then
printf 'Environment=%s=%s' "$key" "$value"
else
printf '# Environment=%s=%s' "$key" "$placeholder"
fi
}
RENDERED_EXEC_START="ExecStart=$(systemd_quote_arg "$AUTH_MONITOR_PATH")"
RENDERED_NTFY_LINE="$(render_environment_line "NOTIFY_NTFY" "openclaw-alerts" "$NTFY_TOPIC")"
RENDERED_PHONE_LINE="$(render_environment_line "NOTIFY_PHONE" "+1234567890" "$PHONE_NUMBER")"
FOUND_EXEC_START=0
FOUND_NTFY=0
FOUND_PHONE=0
while IFS= read -r line || [ -n "$line" ]; do
if [[ "$line" =~ ^[[:space:]]*ExecStart=.*$ ]]; then
printf '%s\n' "$RENDERED_EXEC_START"
FOUND_EXEC_START=1
elif [[ "$line" =~ ^[[:space:]]*#?[[:space:]]*Environment=NOTIFY_NTFY=.*$ ]]; then
printf '%s\n' "$RENDERED_NTFY_LINE"
FOUND_NTFY=1
elif [[ "$line" =~ ^[[:space:]]*#?[[:space:]]*Environment=NOTIFY_PHONE=.*$ ]]; then
printf '%s\n' "$RENDERED_PHONE_LINE"
FOUND_PHONE=1
else
printf '%s\n' "$line"
fi
done < "$SERVICE_TEMP" > "$SERVICE_RENDERED"
if [ "$FOUND_EXEC_START" -ne 1 ]; then
echo "ERROR: ExecStart line not found in $SERVICE_TEMPLATE" >&2
exit 1
fi
if [ "$FOUND_NTFY" -ne 1 ]; then
echo "ERROR: NOTIFY_NTFY placeholder not found in $SERVICE_TEMPLATE" >&2
exit 1
fi
if [ "$FOUND_PHONE" -ne 1 ]; then
echo "ERROR: NOTIFY_PHONE placeholder not found in $SERVICE_TEMPLATE" >&2
exit 1
fi
mv "$SERVICE_RENDERED" "$SERVICE_TEMP"
mv "$SERVICE_TEMP" "$SERVICE_TARGET"
trap - EXIT
cp "$SCRIPT_DIR/systemd/openclaw-auth-monitor.timer" "$TIMER_TARGET"
systemctl --user daemon-reload
systemctl --user enable --now openclaw-auth-monitor.timer

View File

@@ -723,6 +723,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([
["scripts/run-oxlint-shards.mjs", ["test/scripts/run-oxlint.test.ts"]],
["scripts/run-with-env.mjs", ["test/scripts/run-with-env.test.ts"]],
["scripts/run-node.mjs", ["src/infra/run-node.test.ts"]],
["scripts/setup-auth-system.sh", ["test/scripts/test-projects.test.ts"]],
["scripts/ci-run-timings.mjs", ["test/scripts/ci-run-timings.test.ts"]],
["scripts/docker-e2e.mjs", ["test/scripts/docker-e2e-helper-cli.test.ts"]],
["scripts/docker-e2e-rerun.mjs", ["test/scripts/docker-e2e-helper-cli.test.ts"]],

View File

@@ -1011,6 +1011,25 @@ describe("test-projects args", () => {
).toStrictEqual([]);
});
it("routes auth setup script changes to the focused tooling planner test", () => {
const changedPaths = ["scripts/setup-auth-system.sh"];
expect(resolveChangedTestTargetPlan(changedPaths)).toEqual({
mode: "targets",
targets: ["test/scripts/test-projects.test.ts"],
});
expect(
buildVitestRunPlans(["--changed=origin/main"], process.cwd(), () => changedPaths),
).toEqual([
{
config: "test/vitest/vitest.tooling.config.ts",
forwardedArgs: [],
includePatterns: ["test/scripts/test-projects.test.ts"],
watchMode: false,
},
]);
});
it("keeps core test-only changes on their owning test lane", () => {
const changedPaths = ["src/auto-reply/reply/commands-approve.test.ts"];