From f363836712f76ebdc94dfe76a548473d3f415c01 Mon Sep 17 00:00:00 2001 From: stswangzhiping <59632378+stswangzhiping@users.noreply.github.com> Date: Mon, 4 May 2026 19:25:18 +0800 Subject: [PATCH] fix: git pull in Node.js before calling update-clawd.sh --no-pull; startup service fix; bump to 1.2.9 Co-authored-by: Cursor --- bin/clawd.js | 14 ++++++++++ lib/client.js | 71 ++++++++++++++++++++++++++------------------------- package.json | 2 +- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/bin/clawd.js b/bin/clawd.js index 559193a..1c10cdf 100755 --- a/bin/clawd.js +++ b/bin/clawd.js @@ -11,6 +11,20 @@ const config = require('../lib/config'); const log = require('../lib/logger'); const { pollSms } = require('../drivers/sim/sms-reader'); +// 启动时确保 clawd.service ReadWritePaths 包含 /etc/hosts /etc/hostname(幂等修复) +const fs = require('fs'); +const SERVICE_FILE = '/etc/systemd/system/clawd.service'; +try { + const svc = fs.readFileSync(SERVICE_FILE, 'utf8'); + if (svc.includes('ReadWritePaths=') && !svc.includes('/etc/hosts')) { + const fixed = svc.replace(/ReadWritePaths=([^\n]*)/, (_, rest) => + `ReadWritePaths=${rest.trimEnd()} /etc/hosts /etc/hostname`); + fs.writeFileSync(SERVICE_FILE, fixed, 'utf8'); + exec('systemctl daemon-reload', () => {}); + log.info('clawd', 'clawd.service ReadWritePaths fixed'); + } +} catch (_) {} + // 每次启动绑定 Quectel 串口驱动(失败不影响主流程) const bindScript = path.join(__dirname, '..', 'tools', 'bind-quectel-serial.sh'); exec(`bash "${bindScript}"`, (err, stdout, stderr) => { diff --git a/lib/client.js b/lib/client.js index 30c32fa..5c921c9 100644 --- a/lib/client.js +++ b/lib/client.js @@ -676,48 +676,49 @@ class ClawClient { log.info('upgrade', `收到升级命令: ${CLAWD_VERSION} → ${targetVersion}`); this._sendUpgradeProgress(5, 'starting'); - // 检查脚本是否存在 - if (!fs.existsSync(scriptPath)) { - const err = `升级脚本不存在: ${scriptPath}`; - log.error('upgrade', err); - this._sendUpgradeProgress(0, 'failed', true, err); - return; - } - try { + // Step 1: Node.js 负责 git pull,拿到最新代码(含最新 update-clawd.sh) + this._sendUpgradeProgress(20, '拉取更新中'); await new Promise((resolve, reject) => { - const child = exec(`bash "${scriptPath}" --no-restart`, { timeout: 300_000 }); - - child.stdout.on('data', (data) => { - const line = data.toString().trim(); - log.info('upgrade', line); - - // 根据脚本输出关键字上报进度 - if (line.includes('Fetching latest')) this._sendUpgradeProgress(20, '拉取更新中'); - else if (line.includes('Already up to date')) this._sendUpgradeProgress(100, 'already_up_to_date'); - else if (line.includes('Updating working tree')) this._sendUpgradeProgress(50, '更新文件中'); - else if (line.includes('npm install')) this._sendUpgradeProgress(70, '安装依赖中'); - else if (line.includes('No dependency')) this._sendUpgradeProgress(80, '无需安装依赖'); - else if (line.includes('Current commit')) this._sendUpgradeProgress(90, '即将重启'); - }); - - child.stderr.on('data', (data) => { - log.warn('upgrade', data.toString().trim()); - }); - - child.on('close', (code) => { - if (code === 0) resolve(); - else reject(new Error(`脚本退出码: ${code}`)); - }); - + const gitCmd = [ + `git config --global --add safe.directory "${installDir}" 2>/dev/null || true`, + `cd "${installDir}"`, + `git remote get-url origin 2>/dev/null | grep -q github.com && git remote set-url origin https://git.cutos.ai/claw-daemon/clawd.git || true`, + `git fetch origin`, + `git reset --hard origin/main`, + `git clean -fd`, + ].join(' && '); + const child = exec(gitCmd, { timeout: 120_000 }); + child.stdout.on('data', d => log.info('upgrade', d.toString().trim())); + child.stderr.on('data', d => log.warn('upgrade', d.toString().trim())); + child.on('close', code => code === 0 ? resolve() : reject(new Error(`git pull 失败,退出码: ${code}`))); child.on('error', reject); }); - // 脚本执行成功,通知服务端完成,然后退出让 systemd 重启 + this._sendUpgradeProgress(50, '更新文件中'); + + // Step 2: 调用磁盘上已更新的 update-clawd.sh --no-pull(跳过 git,直接写 service 文件等) + if (!fs.existsSync(scriptPath)) { + throw new Error(`升级脚本不存在: ${scriptPath}`); + } + await new Promise((resolve, reject) => { + const child = exec(`bash "${scriptPath}" --no-pull --no-restart`, { timeout: 180_000 }); + child.stdout.on('data', (data) => { + const line = data.toString().trim(); + log.info('upgrade', line); + if (line.includes('npm install')) this._sendUpgradeProgress(70, '安装依赖中'); + else if (line.includes('No depend')) this._sendUpgradeProgress(80, '无需安装依赖'); + else if (line.includes('Writing serv')) this._sendUpgradeProgress(85, '更新服务配置'); + else if (line.includes('Current comm')) this._sendUpgradeProgress(90, '即将重启'); + }); + child.stderr.on('data', d => log.warn('upgrade', d.toString().trim())); + child.on('close', code => code === 0 ? resolve() : reject(new Error(`脚本退出码: ${code}`))); + child.on('error', reject); + }); + + // 通知服务端完成,延迟 1.5 秒确保消息送达,再退出让 systemd 重启 this._sendUpgradeProgress(100, 'done'); log.info('upgrade', `升级至 v${targetVersion} 完成,即将重启...`); - - // 延迟 1.5 秒确保进度消息送达,再退出 setTimeout(() => process.exit(0), 1500); } catch (e) { diff --git a/package.json b/package.json index fe748eb..fa934c4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawd", - "version": "1.2.8", + "version": "1.2.9", "description": "Claw Box daemon - connects local Linux box to claw.cutos.ai via WebSocket", "main": "lib/client.js", "bin": {