From dc8423f2c0dc6bc2a7708402c494667185d85341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=92=E9=9B=B2?= <137844255@qq.com> Date: Tue, 24 Feb 2026 11:22:55 +0800 Subject: [PATCH] fix: back up existing systemd unit before overwriting on update (#24350) (#24937) When `openclaw update` regenerates the systemd service file, any user customizations to ExecStart (e.g. proxychains4 wrapper) are silently lost. Now the existing unit file is copied to `.bak` before writing the new one, so users can restore their customizations. The backup path is printed in the install output so users are aware. Co-authored-by: echoVic --- src/daemon/systemd.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/daemon/systemd.ts b/src/daemon/systemd.ts index 0a295436df8..0e1dc5541ba 100644 --- a/src/daemon/systemd.ts +++ b/src/daemon/systemd.ts @@ -193,6 +193,18 @@ export async function installSystemdService({ const unitPath = resolveSystemdUnitPath(env); await fs.mkdir(path.dirname(unitPath), { recursive: true }); + + // Preserve user customizations: back up existing unit file before overwriting. + let backedUp = false; + try { + await fs.access(unitPath); + const backupPath = `${unitPath}.bak`; + await fs.copyFile(unitPath, backupPath); + backedUp = true; + } catch { + // File does not exist yet — nothing to back up. + } + const serviceDescription = resolveGatewayServiceDescription({ env, environment, description }); const unit = buildSystemdUnit({ description: serviceDescription, @@ -227,6 +239,14 @@ export async function installSystemdService({ label: "Installed systemd service", value: unitPath, }, + ...(backedUp + ? [ + { + label: "Previous unit backed up to", + value: `${unitPath}.bak`, + }, + ] + : []), ], { leadingBlankLine: true }, );