Преглед изворни кода

fix: 跨挂载点迁移技能目录时改为复制后删除(systemd ReadWritePaths 下改名报 EXDEV)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jerry Liang пре 1 недеља
родитељ
комит
f6ba43a8e3
1 измењених фајлова са 11 додато и 2 уклоњено
  1. 11 2
      apps/server/src/app.ts

+ 11 - 2
apps/server/src/app.ts

@@ -81,7 +81,10 @@ export function createApp(log: AppLogger, opts: { db?: DB; providers?: Partial<R
 
 export type App = ReturnType<typeof createApp>
 
-/** 技能生效目录从 data/ 下移到顶层 managed-skills/ 后,一次性搬走旧目录(同一文件系统,直接改名) */
+/**
+ * 技能生效目录从 data/ 下移到顶层 managed-skills/ 后,一次性搬走旧目录。
+ * systemd 的 ReadWritePaths 把每个目录单独挂载,跨目录改名会报 EXDEV,此时改为复制后删除
+ */
 function migrateManagedSkillDirs(log: AppLogger) {
   const moves: [string, string][] = [
     [path.join(config.dataDir, 'data', 'community-skills'), communitySkillsDir()],
@@ -94,7 +97,13 @@ function migrateManagedSkillDirs(log: AppLogger) {
       continue
     }
     fs.mkdirSync(path.dirname(to), { recursive: true })
-    fs.renameSync(from, to)
+    try {
+      fs.renameSync(from, to)
+    } catch (e) {
+      if ((e as NodeJS.ErrnoException).code !== 'EXDEV') throw e
+      fs.cpSync(from, to, { recursive: true, verbatimSymlinks: true, preserveTimestamps: true })
+      fs.rmSync(from, { recursive: true, force: true })
+    }
     log.info({ from, to }, '技能目录已迁移')
   }
 }