forked from NYANDEV/forgejo
fix #580
This commit is contained in:
parent
b6437b5a4c
commit
d75013a0e8
10 changed files with 65 additions and 13 deletions
|
@ -257,6 +257,12 @@ CONN =
|
||||||
|
|
||||||
[git]
|
[git]
|
||||||
MAX_GITDIFF_LINES = 10000
|
MAX_GITDIFF_LINES = 10000
|
||||||
|
; Arguments for command 'git fsck', e.g.: "--unreachable --tags"
|
||||||
|
; see more on http://git-scm.com/docs/git-fsck/1.7.5
|
||||||
|
FSCK_ARGS =
|
||||||
|
; Arguments for command 'git gc', e.g.: "--aggressive --auto"
|
||||||
|
; see more on http://git-scm.com/docs/git-gc/1.7.5
|
||||||
|
GC_ARGS =
|
||||||
|
|
||||||
[i18n]
|
[i18n]
|
||||||
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL
|
LANGS = en-US,zh-CN,zh-HK,de-DE,fr-CA,nl-NL
|
||||||
|
|
|
@ -476,6 +476,8 @@ dashboard.delete_inactivate_accounts = Delete all inactive accounts
|
||||||
dashboard.delete_inactivate_accounts_success = All inactivate accounts have been deleted successfully.
|
dashboard.delete_inactivate_accounts_success = All inactivate accounts have been deleted successfully.
|
||||||
dashboard.delete_repo_archives = Delete all repositories archives
|
dashboard.delete_repo_archives = Delete all repositories archives
|
||||||
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
|
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully.
|
||||||
|
dashboard.git_gc_repos = Do garbage collection on repositories
|
||||||
|
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
|
||||||
dashboard.server_uptime = Server Uptime
|
dashboard.server_uptime = Server Uptime
|
||||||
dashboard.current_goroutine = Current Goroutines
|
dashboard.current_goroutine = Current Goroutines
|
||||||
dashboard.current_memory_usage = Current Memory Usage
|
dashboard.current_memory_usage = Current Memory Usage
|
||||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/gogits/gogs/modules/setting"
|
"github.com/gogits/gogs/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VER = "0.5.8.1128 Beta"
|
const APP_VER = "0.5.8.1130 Beta"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
|
@ -1140,18 +1140,8 @@ type SearchOption struct {
|
||||||
Private bool
|
Private bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterSQLInject tries to prevent SQL injection.
|
|
||||||
func FilterSQLInject(key string) string {
|
|
||||||
key = strings.TrimSpace(key)
|
|
||||||
key = strings.Split(key, " ")[0]
|
|
||||||
key = strings.Replace(key, ",", "", -1)
|
|
||||||
return key
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchRepositoryByName returns given number of repositories whose name contains keyword.
|
// SearchRepositoryByName returns given number of repositories whose name contains keyword.
|
||||||
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
|
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
|
||||||
// Prevent SQL inject.
|
|
||||||
opt.Keyword = FilterSQLInject(opt.Keyword)
|
|
||||||
if len(opt.Keyword) == 0 {
|
if len(opt.Keyword) == 0 {
|
||||||
return repos, nil
|
return repos, nil
|
||||||
}
|
}
|
||||||
|
@ -1183,6 +1173,47 @@ func DeleteRepositoryArchives() error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GitFsck calls 'git fsck' to check repository health.
|
||||||
|
func GitFsck() {
|
||||||
|
args := append([]string{"fsck"}, setting.GitFsckArgs...)
|
||||||
|
if err := x.Where("id > 0").Iterate(new(Repository),
|
||||||
|
func(idx int, bean interface{}) error {
|
||||||
|
repo := bean.(*Repository)
|
||||||
|
if err := repo.GetOwner(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
repoPath := RepoPath(repo.Owner.Name, repo.Name)
|
||||||
|
_, _, err := process.ExecDir(-1, repoPath, "Repository health check", "git", args...)
|
||||||
|
if err != nil {
|
||||||
|
desc := fmt.Sprintf("Fail to health check repository(%s)", repoPath)
|
||||||
|
log.Warn(desc)
|
||||||
|
if err = CreateRepositoryNotice(desc); err != nil {
|
||||||
|
log.Error(4, "Fail to add notice: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
log.Error(4, "repo.Fsck: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GitGcRepos() error {
|
||||||
|
args := append([]string{"gc"}, setting.GitGcArgs...)
|
||||||
|
return x.Where("id > 0").Iterate(new(Repository),
|
||||||
|
func(idx int, bean interface{}) error {
|
||||||
|
repo := bean.(*Repository)
|
||||||
|
if err := repo.GetOwner(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, stderr, err := process.ExecDir(-1, RepoPath(repo.Owner.Name, repo.Name), "Repository garbage collection", "git", args...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%v: %v", err, stderr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// __ __ __ .__
|
// __ __ __ .__
|
||||||
// / \ / \_____ _/ |_ ____ | |__
|
// / \ / \_____ _/ |_ ____ | |__
|
||||||
// \ \/\/ /\__ \\ __\/ ___\| | \
|
// \ \/\/ /\__ \\ __\/ ___\| | \
|
||||||
|
|
|
@ -628,7 +628,6 @@ func GetUserByEmail(email string) (*User, error) {
|
||||||
|
|
||||||
// SearchUserByName returns given number of users whose name contains keyword.
|
// SearchUserByName returns given number of users whose name contains keyword.
|
||||||
func SearchUserByName(opt SearchOption) (us []*User, err error) {
|
func SearchUserByName(opt SearchOption) (us []*User, err error) {
|
||||||
opt.Keyword = FilterSQLInject(opt.Keyword)
|
|
||||||
if len(opt.Keyword) == 0 {
|
if len(opt.Keyword) == 0 {
|
||||||
return us, nil
|
return us, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,10 @@ import (
|
||||||
var c = New()
|
var c = New()
|
||||||
|
|
||||||
func NewCronContext() {
|
func NewCronContext() {
|
||||||
|
models.GitFsck()
|
||||||
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate)
|
c.AddFunc("Update mirrors", "@every 1h", models.MirrorUpdate)
|
||||||
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.WebhookTaskInterval), models.DeliverHooks)
|
c.AddFunc("Deliver hooks", fmt.Sprintf("@every %dm", setting.WebhookTaskInterval), models.DeliverHooks)
|
||||||
|
c.AddFunc("Repository health check", "@every 1h", models.GitFsck)
|
||||||
c.Start()
|
c.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,8 @@ var (
|
||||||
|
|
||||||
// Git settings.
|
// Git settings.
|
||||||
MaxGitDiffLines int
|
MaxGitDiffLines int
|
||||||
|
GitFsckArgs []string
|
||||||
|
GitGcArgs []string
|
||||||
|
|
||||||
// I18n settings.
|
// I18n settings.
|
||||||
Langs, Names []string
|
Langs, Names []string
|
||||||
|
@ -288,6 +290,8 @@ func NewConfigContext() {
|
||||||
DisableGravatar = Cfg.MustBool("picture", "DISABLE_GRAVATAR")
|
DisableGravatar = Cfg.MustBool("picture", "DISABLE_GRAVATAR")
|
||||||
|
|
||||||
MaxGitDiffLines = Cfg.MustInt("git", "MAX_GITDIFF_LINES", 10000)
|
MaxGitDiffLines = Cfg.MustInt("git", "MAX_GITDIFF_LINES", 10000)
|
||||||
|
GitFsckArgs = Cfg.MustValueArray("git", "FSCK_ARGS", " ")
|
||||||
|
GitGcArgs = Cfg.MustValueArray("git", "GC_ARGS", " ")
|
||||||
|
|
||||||
Langs = Cfg.MustValueArray("i18n", "LANGS", ",")
|
Langs = Cfg.MustValueArray("i18n", "LANGS", ",")
|
||||||
Names = Cfg.MustValueArray("i18n", "NAMES", ",")
|
Names = Cfg.MustValueArray("i18n", "NAMES", ",")
|
||||||
|
|
|
@ -117,6 +117,7 @@ const (
|
||||||
CLEAN_UNBIND_OAUTH AdminOperation = iota + 1
|
CLEAN_UNBIND_OAUTH AdminOperation = iota + 1
|
||||||
CLEAN_INACTIVATE_USER
|
CLEAN_INACTIVATE_USER
|
||||||
CLEAN_REPO_ARCHIVES
|
CLEAN_REPO_ARCHIVES
|
||||||
|
GIT_GC_REPOS
|
||||||
)
|
)
|
||||||
|
|
||||||
func Dashboard(ctx *middleware.Context) {
|
func Dashboard(ctx *middleware.Context) {
|
||||||
|
@ -140,6 +141,9 @@ func Dashboard(ctx *middleware.Context) {
|
||||||
case CLEAN_REPO_ARCHIVES:
|
case CLEAN_REPO_ARCHIVES:
|
||||||
success = ctx.Tr("admin.dashboard.delete_repo_archives_success")
|
success = ctx.Tr("admin.dashboard.delete_repo_archives_success")
|
||||||
err = models.DeleteRepositoryArchives()
|
err = models.DeleteRepositoryArchives()
|
||||||
|
case GIT_GC_REPOS:
|
||||||
|
success = ctx.Tr("admin.dashboard.git_gc_repos_success")
|
||||||
|
err = models.GitGcRepos()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.5.8.1128 Beta
|
0.5.8.1130 Beta
|
|
@ -44,6 +44,10 @@
|
||||||
<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
|
<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
|
||||||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=3">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=3">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td>
|
||||||
|
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=4">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue