Skip to content

Commit 39f376f

Browse files
committed
Fail mirroring more gracefully:
* reuse recoverable error checks across mirror_pull * add new cases for 'cannot lock ref/not our ref' (race condition in fetch) and 'Unable to create/lock" * move lfs sync right after commit graph write, and before other maintenance which may fail * try a prune for 'broken reference' as well as 'not our ref' * always sync LFS right after commit graph write, and before other maintenance which may fail
1 parent 82bc8b8 commit 39f376f

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

services/mirror/mirror_pull.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,20 @@ func pruneBrokenReferences(ctx context.Context,
235235
return pruneErr
236236
}
237237

238+
// checkRecoverableSyncError takes an error message from a git fetch command and returns false if it should be a fatal/blocking error
239+
func checkRecoverableSyncError(stderrMessage string) bool {
240+
switch {
241+
case strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken"):
242+
case strings.Contains(stderrMessage, "remote error") && strings.Contains(stderrMessage, "not our ref"):
243+
case strings.Contains(stderrMessage, "cannot lock ref") && strings.Contains(stderrMessage, "but expected"):
244+
case strings.Contains(stderrMessage, "Unable to create") && strings.Contains(stderrMessage, ".lock"):
245+
default:
246+
return true
247+
}
248+
249+
return false
250+
}
251+
238252
// runSync returns true if sync finished without error.
239253
func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bool) {
240254
repoPath := m.Repo.RepoPath()
@@ -275,7 +289,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
275289
stdoutMessage := util.SanitizeCredentialURLs(stdout)
276290

277291
// Now check if the error is a resolve reference due to broken reference
278-
if strings.Contains(stderr, "unable to resolve reference") && strings.Contains(stderr, "reference broken") {
292+
if checkRecoverableSyncError(stderr) {
279293
log.Warn("SyncMirrors [repo: %-v]: failed to update mirror repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
280294
err = nil
281295

@@ -324,6 +338,15 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
324338
return nil, false
325339
}
326340

341+
if m.LFS && setting.LFS.StartServer {
342+
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
343+
endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
344+
lfsClient := lfs.NewClient(endpoint, nil)
345+
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
346+
log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
347+
}
348+
}
349+
327350
log.Trace("SyncMirrors [repo: %-v]: syncing branches...", m.Repo)
328351
if _, err = repo_module.SyncRepoBranchesWithRepo(ctx, m.Repo, gitRepo, 0); err != nil {
329352
log.Error("SyncMirrors [repo: %-v]: failed to synchronize branches: %v", m.Repo, err)
@@ -333,15 +356,6 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
333356
if err = repo_module.SyncReleasesWithTags(ctx, m.Repo, gitRepo); err != nil {
334357
log.Error("SyncMirrors [repo: %-v]: failed to synchronize tags to releases: %v", m.Repo, err)
335358
}
336-
337-
if m.LFS && setting.LFS.StartServer {
338-
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
339-
endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
340-
lfsClient := lfs.NewClient(endpoint, nil)
341-
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
342-
log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo, err)
343-
}
344-
}
345359
gitRepo.Close()
346360

347361
log.Trace("SyncMirrors [repo: %-v]: updating size of repository", m.Repo)
@@ -368,7 +382,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
368382
stdoutMessage := util.SanitizeCredentialURLs(stdout)
369383

370384
// Now check if the error is a resolve reference due to broken reference
371-
if strings.Contains(stderrMessage, "unable to resolve reference") && strings.Contains(stderrMessage, "reference broken") {
385+
if checkRecoverableSyncError(stderrMessage) {
372386
log.Warn("SyncMirrors [repo: %-v Wiki]: failed to update mirror wiki repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err)
373387
err = nil
374388

0 commit comments

Comments
 (0)