mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	fix #580
This commit is contained in:
		@@ -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>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user