@@ -760,6 +760,8 @@ dashboard.delete_inactivate_accounts = Delete all inactive accounts | |||
dashboard.delete_inactivate_accounts_success = All inactivate accounts have been deleted successfully. | |||
dashboard.delete_repo_archives = Delete all repositories archives | |||
dashboard.delete_repo_archives_success = All repositories archives have been deleted successfully. | |||
dashboard.delete_missing_repos = Delete all repository records that lost Git files | |||
dashboard.delete_missing_repos_success = All repository records that lost Git files 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.resync_all_sshkeys = Rewrite '.ssh/authorized_keys' file (caution: non-Gogs keys will be lost) |
@@ -1325,6 +1325,42 @@ func DeleteRepositoryArchives() error { | |||
}) | |||
} | |||
// DeleteMissingRepositories deletes all repository records that lost Git files. | |||
func DeleteMissingRepositories() error { | |||
repos := make([]*Repository, 0, 5) | |||
if err := x.Where("id > 0").Iterate(new(Repository), | |||
func(idx int, bean interface{}) error { | |||
repo := bean.(*Repository) | |||
repoPath, err := repo.RepoPath() | |||
if err != nil { | |||
return fmt.Errorf("RepoPath [%d]: %v", repo.ID, err) | |||
} | |||
if !com.IsDir(repoPath) { | |||
repos = append(repos, repo) | |||
} | |||
return nil | |||
}); err != nil { | |||
if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteMissingRepositories: %v", err)); err2 != nil { | |||
log.Error(4, "CreateRepositoryNotice: %v", err2) | |||
} | |||
return nil | |||
} | |||
if len(repos) == 0 { | |||
return nil | |||
} | |||
for _, repo := range repos { | |||
if err := DeleteRepository(repo.OwnerID, repo.ID); err != nil { | |||
if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteRepository [%d]: %v", repo.ID, err)); err2 != nil { | |||
log.Error(4, "CreateRepositoryNotice: %v", err2) | |||
} | |||
} | |||
} | |||
return nil | |||
} | |||
// RewriteRepositoryUpdateHook rewrites all repositories' update hook. | |||
func RewriteRepositoryUpdateHook() error { | |||
return x.Where("id > 0").Iterate(new(Repository), |
@@ -116,6 +116,7 @@ type AdminOperation int | |||
const ( | |||
CLEAN_INACTIVATE_USER AdminOperation = iota + 1 | |||
CLEAN_REPO_ARCHIVES | |||
CLEAN_MISSING_REPOS | |||
GIT_GC_REPOS | |||
SYNC_SSH_AUTHORIZED_KEY | |||
SYNC_REPOSITORY_UPDATE_HOOK | |||
@@ -139,6 +140,9 @@ func Dashboard(ctx *middleware.Context) { | |||
case CLEAN_REPO_ARCHIVES: | |||
success = ctx.Tr("admin.dashboard.delete_repo_archives_success") | |||
err = models.DeleteRepositoryArchives() | |||
case CLEAN_MISSING_REPOS: | |||
success = ctx.Tr("admin.dashboard.delete_missing_repos_success") | |||
err = models.DeleteMissingRepositories() | |||
case GIT_GC_REPOS: | |||
success = ctx.Tr("admin.dashboard.git_gc_repos_success") | |||
err = models.GitGcRepos() |
@@ -28,17 +28,21 @@ | |||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=2">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td> | |||
</tr> | |||
<tr> | |||
<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td> | |||
<td>{{.i18n.Tr "admin.dashboard.delete_missing_repos"}}</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> | |||
<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td> | |||
<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> | |||
<tr> | |||
<td>{{.i18n.Tr "admin.dashboard.resync_all_update_hooks"}}</td> | |||
<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td> | |||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td> | |||
</tr> | |||
<tr> | |||
<td>{{.i18n.Tr "admin.dashboard.resync_all_update_hooks"}}</td> | |||
<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=6">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> |