From 373c531ff29cd9d81e8f488bb5f76462dd4fcad8 Mon Sep 17 00:00:00 2001 From: zeripath Date: Wed, 13 Oct 2021 20:47:02 +0100 Subject: [PATCH] Ensure that git daemon export ok is created for mirrors (#17243) Backport #17243 There is an issue with #16508 where it appears that create repo requires that the repo does not exist. This causes #17241 where an error is reported because of this. This PR fixes this and also runs update-server-info for mirrors and generated repos. Fix #17241 Signed-off-by: Andrew Thornton --- models/repo.go | 67 +++++++++++++++++++++------------- modules/repository/adopt.go | 3 ++ modules/repository/create.go | 4 ++ modules/repository/fork.go | 7 +++- modules/repository/generate.go | 11 ++++++ modules/repository/repo.go | 15 ++++++++ 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/models/repo.go b/models/repo.go index 9cbb7977e3547..d56728ef36dba 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1152,16 +1152,6 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO return fmt.Errorf("recalculateAccesses: %v", err) } - if u.Visibility == api.VisibleTypePublic && !repo.IsPrivate { - // Create/Remove git-daemon-export-ok for git-daemon... - daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`) - if f, err := os.Create(daemonExportFile); err != nil { - log.Error("Failed to create %s: %v", daemonExportFile, err) - } else { - f.Close() - } - } - if setting.Service.AutoWatchNewRepos { if err = watchRepo(ctx.e, doer.ID, repo.ID, true); err != nil { return fmt.Errorf("watchRepo: %v", err) @@ -1175,6 +1165,46 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO return nil } +// CheckDaemonExportOK creates/removes git-daemon-export-ok for git-daemon... +func (repo *Repository) CheckDaemonExportOK() error { + return repo.checkDaemonExportOK(x) +} + +// CheckDaemonExportOKCtx creates/removes git-daemon-export-ok for git-daemon... +func (repo *Repository) CheckDaemonExportOKCtx(ctx DBContext) error { + return repo.checkDaemonExportOK(ctx.e) +} + +func (repo *Repository) checkDaemonExportOK(e Engine) error { + if err := repo.getOwner(e); err != nil { + return err + } + + // Create/Remove git-daemon-export-ok for git-daemon... + daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`) + + isExist, err := util.IsExist(daemonExportFile) + if err != nil { + log.Error("Unable to check if %s exists. Error: %v", daemonExportFile, err) + return err + } + + isPublic := !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePublic + if !isPublic && isExist { + if err = util.Remove(daemonExportFile); err != nil { + log.Error("Failed to remove %s: %v", daemonExportFile, err) + } + } else if isPublic && !isExist { + if f, err := os.Create(daemonExportFile); err != nil { + log.Error("Failed to create %s: %v", daemonExportFile, err) + } else { + f.Close() + } + } + + return nil +} + func countRepositories(userID int64, private bool) int64 { sess := x.Where("id > 0") @@ -1324,24 +1354,9 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e } // Create/Remove git-daemon-export-ok for git-daemon... - daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`) - isExist, err := util.IsExist(daemonExportFile) - isPublic := !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePublic - if err != nil { - log.Error("Unable to check if %s exists. Error: %v", daemonExportFile, err) + if err := repo.checkDaemonExportOK(e); err != nil { return err } - if !isPublic && isExist { - if err = util.Remove(daemonExportFile); err != nil { - log.Error("Failed to remove %s: %v", daemonExportFile, err) - } - } else if isPublic && !isExist { - if f, err := os.Create(daemonExportFile); err != nil { - log.Error("Failed to create %s: %v", daemonExportFile, err) - } else { - f.Close() - } - } forkRepos, err := getRepositoriesByForkID(e, repo.ID) if err != nil { diff --git a/modules/repository/adopt.go b/modules/repository/adopt.go index 321e6ab7672cd..cdcf7104e0416 100644 --- a/modules/repository/adopt.go +++ b/modules/repository/adopt.go @@ -66,6 +66,9 @@ func AdoptRepository(doer, u *models.User, opts models.CreateRepoOptions) (*mode if err := adoptRepository(ctx, repoPath, doer, repo, opts); err != nil { return fmt.Errorf("createDelegateHooks: %v", err) } + if err := repo.CheckDaemonExportOKCtx(ctx); err != nil { + return fmt.Errorf("checkDaemonExportOK: %v", err) + } // Initialize Issue Labels if selected if len(opts.IssueLabels) > 0 { diff --git a/modules/repository/create.go b/modules/repository/create.go index 5eac03836e1bb..8065543d83ca9 100644 --- a/modules/repository/create.go +++ b/modules/repository/create.go @@ -103,6 +103,10 @@ func CreateRepository(doer, u *models.User, opts models.CreateRepoOptions) (*mod } } + if err := repo.CheckDaemonExportOKCtx(ctx); err != nil { + return fmt.Errorf("checkDaemonExportOK: %v", err) + } + if stdout, err := git.NewCommand("update-server-info"). SetDescription(fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath)). RunInDir(repoPath); err != nil { diff --git a/modules/repository/fork.go b/modules/repository/fork.go index 6025faca33dbc..4cff4c24f8273 100644 --- a/modules/repository/fork.go +++ b/modules/repository/fork.go @@ -95,14 +95,17 @@ func ForkRepository(doer, owner *models.User, oldRepo *models.Repository, name, needsRollback = true repoPath := models.RepoPath(owner.Name, repo.Name) - if stdout, err := git.NewCommand( - "clone", "--bare", oldRepoPath, repoPath). + if stdout, err := git.NewCommand("clone", "--bare", oldRepoPath, repoPath). SetDescription(fmt.Sprintf("ForkRepository(git clone): %s to %s", oldRepo.FullName(), repo.FullName())). RunInDirTimeout(10*time.Minute, ""); err != nil { log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, oldRepo, stdout, err) return fmt.Errorf("git clone: %v", err) } + if err := repo.CheckDaemonExportOKCtx(ctx); err != nil { + return fmt.Errorf("checkDaemonExportOK: %v", err) + } + if stdout, err := git.NewCommand("update-server-info"). SetDescription(fmt.Sprintf("ForkRepository(git update-server-info): %s", repo.FullName())). RunInDir(repoPath); err != nil { diff --git a/modules/repository/generate.go b/modules/repository/generate.go index 1ba457fb3a551..a7adce4d02d0d 100644 --- a/modules/repository/generate.go +++ b/modules/repository/generate.go @@ -275,5 +275,16 @@ func GenerateRepository(ctx models.DBContext, doer, owner *models.User, template return generateRepo, err } + if err = generateRepo.CheckDaemonExportOKCtx(ctx); err != nil { + return generateRepo, fmt.Errorf("checkDaemonExportOK: %v", err) + } + + if stdout, err := git.NewCommand("update-server-info"). + SetDescription(fmt.Sprintf("GenerateRepository(git update-server-info): %s", repoPath)). + RunInDir(repoPath); err != nil { + log.Error("GenerateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", generateRepo, stdout, err) + return generateRepo, fmt.Errorf("error in GenerateRepository(git update-server-info): %v", err) + } + return generateRepo, nil } diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 08531c04ed3e1..45308ad1629e8 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -95,6 +95,21 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models. } } + if repo.OwnerID == u.ID { + repo.Owner = u + } + + if err = repo.CheckDaemonExportOK(); err != nil { + return repo, fmt.Errorf("checkDaemonExportOK: %v", err) + } + + if stdout, err := git.NewCommandContext(ctx, "update-server-info"). + SetDescription(fmt.Sprintf("MigrateRepositoryGitData(git update-server-info): %s", repoPath)). + RunInDir(repoPath); err != nil { + log.Error("MigrateRepositoryGitData(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) + return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %v", err) + } + gitRepo, err := git.OpenRepository(repoPath) if err != nil { return repo, fmt.Errorf("OpenRepository: %v", err)