mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-18 11:10:00 +00:00
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 <wxiaoguang@gmail.com>
This commit is contained in:
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user