Skip to content

Commit 214c8ca

Browse files
fix(repo-mirror): stage tarball extraction under reposPath to avoid cross-device rename
Containerised manager has /tmp and /workspace on different volumes, so the final fsp.rename(stagingDir, fullPath) was failing with EXDEV. Move both the receive staging dir and the gitignore exclude staging into a sibling .ocm-staging directory under getReposPath() so the rename is always intra-filesystem.
1 parent bbf3461 commit 214c8ca

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

backend/src/routes/internal/repo-mirror.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import type { Database } from 'bun:sqlite'
33
import { spawn } from 'child_process'
44
import { pipeline } from 'stream/promises'
55
import { Readable } from 'stream'
6-
import { mkdtempSync, readdirSync, statSync, existsSync, writeFileSync } from 'fs'
6+
import { mkdtempSync, mkdirSync, readdirSync, statSync, existsSync, writeFileSync } from 'fs'
77
import { join } from 'path'
8-
import { tmpdir } from 'os'
98
import * as fsp from 'fs/promises'
9+
import { getReposPath } from '@opencode-manager/shared/config/env'
1010
import { getRepoById, updateLastPulled, updateRepoBranch, deleteRepo } from '../../db/queries'
1111
import { ensureMirrorTargetPath, createRepoRow, isRepoInUse } from '../../services/repo'
1212
import { logger } from '../../utils/logger'
@@ -62,7 +62,9 @@ export function createInternalRepoMirrorRoutes(db: Database) {
6262
let staging: string | undefined
6363
let oldDirMoved = false
6464
try {
65-
staging = mkdtempSync(join(tmpdir(), 'ocm-mirror-recv-'))
65+
const stagingParent = join(getReposPath(), '.ocm-staging')
66+
mkdirSync(stagingParent, { recursive: true })
67+
staging = mkdtempSync(join(stagingParent, 'recv-'))
6668

6769
const isGzip = c.req.header('Content-Encoding') === 'gzip'
6870
const tarArgs = ['-x', '-f', '-', '-C', staging]
@@ -172,7 +174,9 @@ export function createInternalRepoMirrorRoutes(db: Database) {
172174
try {
173175
const ignored = await gitOut(fullPath, ['ls-files', '--others', '--ignored', '--exclude-standard', '--directory'])
174176
if (ignored.trim()) {
175-
ignoreFile = mkdtempSync(join(tmpdir(), 'ocm-mirror-exclude-'))
177+
const excludeParent = join(getReposPath(), '.ocm-staging')
178+
mkdirSync(excludeParent, { recursive: true })
179+
ignoreFile = mkdtempSync(join(excludeParent, 'exclude-'))
176180
writeFileSync(join(ignoreFile, '.gitignore'), ignored)
177181
excludeArgs.push('--exclude-from', join(ignoreFile, '.gitignore'))
178182
}

0 commit comments

Comments
 (0)