[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 |
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 |
"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()) |
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 | ||||
} | } | ||||
}) | }) | ||||
} | } | ||||
// 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 | |||||
}) | |||||
} | |||||
// __ __ __ .__ | // __ __ __ .__ | ||||
// / \ / \_____ _/ |_ ____ | |__ | // / \ / \_____ _/ |_ ____ | |__ | ||||
// \ \/\/ /\__ \\ __\/ ___\| | \ | // \ \/\/ /\__ \\ __\/ ___\| | \ |
// 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 | ||||
} | } |
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() | ||||
} | } | ||||
// Git settings. | // Git settings. | ||||
MaxGitDiffLines int | MaxGitDiffLines int | ||||
GitFsckArgs []string | |||||
GitGcArgs []string | |||||
// I18n settings. | // I18n settings. | ||||
Langs, Names []string | Langs, Names []string | ||||
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", ",") |
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) { | ||||
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 { |
0.5.8.1128 Beta | |||||
0.5.8.1130 Beta |
<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> |