From 4e837fed97beb4f9594b1e5a34fd597ba7586383 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 May 2026 07:19:25 +0000 Subject: [PATCH] chore(doctor): remove four obsolete doctor check implementations (#37728) Removed check names: - disable-mirror-actions-unit - check-old-archives - synchronize-repo-heads - authorized-keys Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com> Co-authored-by: wxiaoguang --- services/doctor/actions.go | 70 ------------------- services/doctor/authorizedkeys.go | 100 ---------------------------- services/doctor/checkOldArchives.go | 57 ---------------- services/doctor/heads.go | 92 ------------------------- 4 files changed, 319 deletions(-) delete mode 100644 services/doctor/actions.go delete mode 100644 services/doctor/authorizedkeys.go delete mode 100644 services/doctor/checkOldArchives.go delete mode 100644 services/doctor/heads.go diff --git a/services/doctor/actions.go b/services/doctor/actions.go deleted file mode 100644 index 28e26c88eb..0000000000 --- a/services/doctor/actions.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package doctor - -import ( - "context" - "fmt" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" - unit_model "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/optional" - repo_service "code.gitea.io/gitea/services/repository" -) - -func disableMirrorActionsUnit(ctx context.Context, logger log.Logger, autofix bool) error { - var reposToFix []*repo_model.Repository - - for page := 1; ; page++ { - repos, _, err := repo_model.SearchRepository(ctx, repo_model.SearchRepoOptions{ - ListOptions: db.ListOptions{ - PageSize: repo_model.RepositoryListDefaultPageSize, - Page: page, - }, - Mirror: optional.Some(true), - }) - if err != nil { - return fmt.Errorf("SearchRepository: %w", err) - } - if len(repos) == 0 { - break - } - - for _, repo := range repos { - if repo.UnitEnabled(ctx, unit_model.TypeActions) { - reposToFix = append(reposToFix, repo) - } - } - } - - if len(reposToFix) == 0 { - logger.Info("Found no mirror with actions unit enabled") - } else { - logger.Warn("Found %d mirrors with actions unit enabled", len(reposToFix)) - } - if !autofix || len(reposToFix) == 0 { - return nil - } - - for _, repo := range reposToFix { - if err := repo_service.UpdateRepositoryUnits(ctx, repo, nil, []unit_model.Type{unit_model.TypeActions}); err != nil { - return err - } - } - logger.Info("Fixed %d mirrors with actions unit enabled", len(reposToFix)) - - return nil -} - -func init() { - Register(&Check{ - Title: "Disable the actions unit for all mirrors", - Name: "disable-mirror-actions-unit", - IsDefault: false, - Run: disableMirrorActionsUnit, - Priority: 9, - }) -} diff --git a/services/doctor/authorizedkeys.go b/services/doctor/authorizedkeys.go deleted file mode 100644 index fe1dc639e8..0000000000 --- a/services/doctor/authorizedkeys.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package doctor - -import ( - "bufio" - "bytes" - "context" - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - asymkey_model "code.gitea.io/gitea/models/asymkey" - "code.gitea.io/gitea/modules/container" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" - asymkey_service "code.gitea.io/gitea/services/asymkey" -) - -func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) error { - if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile { - return nil - } - - fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys") - f, err := os.Open(fPath) - if err != nil { - if !autofix { - logger.Critical("Unable to open authorized_keys file. ERROR: %v", err) - return fmt.Errorf("Unable to open authorized_keys file. ERROR: %w", err) - } - logger.Warn("Unable to open authorized_keys. (ERROR: %v). Attempting to rewrite...", err) - if err = asymkey_service.RewriteAllPublicKeys(ctx); err != nil { - logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err) - return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %w", err) - } - } - defer f.Close() - - linesInAuthorizedKeys := make(container.Set[string]) - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - if strings.HasPrefix(line, asymkey_model.AuthorizedStringCommentPrefix) { - continue - } - linesInAuthorizedKeys.Add(line) - } - if err = scanner.Err(); err != nil { - return fmt.Errorf("scan: %w", err) - } - // although there is a "defer close" above, here close explicitly before the generating, because it needs to open the file for writing again - _ = f.Close() - - // now we regenerate and check if there are any lines missing - regenerated := &bytes.Buffer{} - if err := asymkey_model.RegeneratePublicKeys(ctx, regenerated); err != nil { - logger.Critical("Unable to regenerate authorized_keys file. ERROR: %v", err) - return fmt.Errorf("Unable to regenerate authorized_keys file. ERROR: %w", err) - } - scanner = bufio.NewScanner(regenerated) - for scanner.Scan() { - line := scanner.Text() - if strings.HasPrefix(line, asymkey_model.AuthorizedStringCommentPrefix) { - continue - } - if linesInAuthorizedKeys.Contains(line) { - continue - } - if !autofix { - logger.Critical( - "authorized_keys file %q is out of date.\nRegenerate it with:\n\t\"%s\"\nor\n\t\"%s\"", - fPath, - "gitea admin regenerate keys", - "gitea doctor --run authorized-keys --fix") - return errors.New(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized-keys --fix"`) - } - logger.Warn("authorized_keys is out of date. Attempting rewrite...") - err = asymkey_service.RewriteAllPublicKeys(ctx) - if err != nil { - logger.Critical("Unable to rewrite authorized_keys file. ERROR: %v", err) - return fmt.Errorf("Unable to rewrite authorized_keys file. ERROR: %w", err) - } - } - return nil -} - -func init() { - Register(&Check{ - Title: "Check if OpenSSH authorized_keys file is up-to-date", - Name: "authorized-keys", - IsDefault: true, - Run: checkAuthorizedKeys, - Priority: 4, - }) -} diff --git a/services/doctor/checkOldArchives.go b/services/doctor/checkOldArchives.go deleted file mode 100644 index fa1a6ccb1d..0000000000 --- a/services/doctor/checkOldArchives.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package doctor - -import ( - "context" - - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/gitrepo" - "code.gitea.io/gitea/modules/log" -) - -func checkOldArchives(ctx context.Context, logger log.Logger, autofix bool) error { - numRepos := 0 - numReposUpdated := 0 - err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { - if repo.IsEmpty { - return nil - } - - isDir, err := gitrepo.IsRepoDirExist(ctx, repo, "archives") - if err != nil { - log.Warn("check if %s is directory failed: %v", repo.FullName(), err) - } - if isDir { - numRepos++ - if autofix { - err := gitrepo.RemoveRepoFileOrDir(ctx, repo, "archives") - if err == nil { - numReposUpdated++ - } else { - log.Warn("remove %s failed: %v", repo.FullName(), err) - } - } - } - return nil - }) - - if autofix { - logger.Info("%d / %d old archives in repository deleted", numReposUpdated, numRepos) - } else { - logger.Info("%d old archives in repository need to be deleted", numRepos) - } - - return err -} - -func init() { - Register(&Check{ - Title: "Check old archives", - Name: "check-old-archives", - IsDefault: false, - Run: checkOldArchives, - Priority: 7, - }) -} diff --git a/services/doctor/heads.go b/services/doctor/heads.go deleted file mode 100644 index 4d34b18e18..0000000000 --- a/services/doctor/heads.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package doctor - -import ( - "context" - - repo_model "code.gitea.io/gitea/models/repo" - "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/git/gitcmd" - "code.gitea.io/gitea/modules/gitrepo" - "code.gitea.io/gitea/modules/log" -) - -func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error { - numRepos := 0 - numHeadsBroken := 0 - numDefaultBranchesBroken := 0 - numReposUpdated := 0 - err := iterateRepositories(ctx, func(repo *repo_model.Repository) error { - numRepos++ - _, _, defaultBranchErr := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("rev-parse").AddDashesAndList(repo.DefaultBranch)) - - head, _, headErr := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("symbolic-ref", "--short", "HEAD")) - - // what we expect: default branch is valid, and HEAD points to it - if headErr == nil && defaultBranchErr == nil && head == repo.DefaultBranch { - return nil - } - - if headErr != nil { - numHeadsBroken++ - } - if defaultBranchErr != nil { - numDefaultBranchesBroken++ - } - - // if default branch is broken, let the user fix that in the UI - if defaultBranchErr != nil { - logger.Warn("Default branch for %s/%s doesn't point to a valid commit", repo.OwnerName, repo.Name) - return nil - } - - // if we're not autofixing, that's all we can do - if !autofix { - return nil - } - - // otherwise, let's try fixing HEAD - err := gitrepo.RunCmd(ctx, repo, gitcmd.NewCommand("symbolic-ref").AddDashesAndList("HEAD", git.BranchPrefix+repo.DefaultBranch)) - if err != nil { - logger.Warn("Failed to fix HEAD for %s/%s: %v", repo.OwnerName, repo.Name, err) - return nil - } - numReposUpdated++ - return nil - }) - if err != nil { - logger.Critical("Error when fixing repo HEADs: %v", err) - } - - if autofix { - logger.Info("Out of %d repos, HEADs for %d are now fixed and HEADS for %d are still broken", numRepos, numReposUpdated, numDefaultBranchesBroken+numHeadsBroken-numReposUpdated) - } else { - if numHeadsBroken == 0 && numDefaultBranchesBroken == 0 { - logger.Info("All %d repos have their HEADs in the correct state", numRepos) - } else { - if numHeadsBroken == 0 && numDefaultBranchesBroken != 0 { - logger.Critical("Default branches are broken for %d/%d repos", numDefaultBranchesBroken, numRepos) - } else if numHeadsBroken != 0 && numDefaultBranchesBroken == 0 { - logger.Warn("HEADs are broken for %d/%d repos", numHeadsBroken, numRepos) - } else { - logger.Critical("Out of %d repos, HEADS are broken for %d and default branches are broken for %d", numRepos, numHeadsBroken, numDefaultBranchesBroken) - } - } - } - - return err -} - -func init() { - Register(&Check{ - Title: "Synchronize repo HEADs", - Name: "synchronize-repo-heads", - IsDefault: true, - Run: synchronizeRepoHeads, - Priority: 7, - }) -}