conf: overhaul repository settings (#5932)

pull/5940/head
ᴜɴᴋɴᴡᴏɴ 2020-02-22 15:22:32 +08:00 committed by GitHub
parent f59a68c531
commit c4a0a40473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 183 additions and 176 deletions

View File

@ -37,6 +37,8 @@ All notable changes to Gogs are documented in this file.
- Configuration option `[other] SHOW_FOOTER_VERSION`
- Configuration option `[server] STATIC_ROOT_PATH`
- Configuration option `[repository] MIRROR_QUEUE_LENGTH`
- Configuration option `[repository] PULL_REQUEST_QUEUE_LENGTH`
---

View File

@ -89,53 +89,48 @@ RSA = 2048
DSA = 1024
[repository]
; Root path for storing repositories's data, default is "~/gogs-repositories"
; The root path for storing managed repositories, default is "~/gogs-repositories"
ROOT =
; The script type server supports, sometimes could be "sh"
; The script type server supports, sometimes could be "sh".
SCRIPT_TYPE = bash
; Default ANSI charset for an unrecognized charset
; Default ANSI charset for an unrecognized charset.
ANSI_CHARSET =
; Force every new repository to be private
; Whether to force every new repository to be private.
FORCE_PRIVATE = false
; Global maximum creation limit of repository per user, -1 means no limit
; The global limit of number of repositories a user can create, -1 means no limit.
MAX_CREATION_LIMIT = -1
; Mirror sync queue length, increase if mirror syncing starts hanging
MIRROR_QUEUE_LENGTH = 1000
; Patch test queue length, increase if pull request patch testing starts hanging
PULL_REQUEST_QUEUE_LENGTH = 1000
; Preferred Licenses to place at the top of the list
; Name must match file name in conf/license or custom/conf/license
PREFERRED_LICENSES = Apache License 2.0,MIT License
; Disable ability to interact with repositories by HTTP protocol
; Preferred Licenses to place at the top of the list.
; Name must match file name in "conf/license" or "custom/conf/license".
PREFERRED_LICENSES = Apache License 2.0, MIT License
; Whether to disable Git interaction with repositories via HTTP/HTTPS protocol.
DISABLE_HTTP_GIT = false
; Enable ability to migrate repository by local path
; Whether to enable ability to migrate repository by server local path.
ENABLE_LOCAL_PATH_MIGRATION = false
; Concurrency is used to retrieve commits information. This variable define
; the maximum number of tasks that can be run at the same time. Usually, the
; value depend of how many CPUs (cores) you have. If the value is set to zero
; or under, Gogs will automatically detect the number of CPUs your system have
COMMITS_FETCH_CONCURRENCY = 0
; Enable render mode for raw file
; Whether to enable render mode for raw file. There are potential security risks.
ENABLE_RAW_FILE_RENDER_MODE = false
; The maximum number of goroutines that can be run at the same time for a single
; fetch request. Usually, the value depend of how many CPU (cores) you have. If
; the value is non-positive, it matchs the number of CPUs available to the application.
COMMITS_FETCH_CONCURRENCY = 0
[repository.editor]
; List of file extensions that should have line wraps in the CodeMirror editor.
; Separate extensions with a comma. To line wrap files without extension, just put a comma
LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd,
; Valid file modes that have a preview API associated with them, such as api/v1/markdown.
; Separate values by commas. Preview tab in edit mode won't show if the file extension doesn't match
; Separate extensions with a comma.
LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd
; Valid file modes that have a preview API associated with them, such as "/api/v1/markdown".
; Separate values by commas. Preview tab in edit mode won't show if the file extension doesn't match.
PREVIEWABLE_FILE_MODES = markdown
[repository.upload]
; Enable repository file uploads.
; Whether to enable repository file uploads.
ENABLED = true
; Path to temporarily store uploads (default path gets cleaned by Gogs in every start)
; The path to temporarily store uploads (content under this path gets wiped out on every start).
TEMP_PATH = data/tmp/uploads
; File types that are allowed to be uploaded, e.g. image/jpeg|image/png. Leave empty means allow any file type
; File types that are allowed to be uploaded, e.g. "image/jpeg|image/png". Leave empty to allow any file type.
ALLOWED_TYPES =
; Maximum size of each file in MB
; The maximum size of each file in MB.
FILE_MAX_SIZE = 3
; Maximum number of files per upload
; The maximum number of files per upload.
MAX_FILES = 5
; Attachment settings for releases

View File

@ -1197,19 +1197,28 @@ config.ssh.listen_host = Listen host
config.ssh.listen_port = Listen port
config.ssh.server_ciphers = Server ciphers
config.repo_config = Repository configuration
config.repo.root_path = Root path
config.repo.script_type = Script type
config.repo.ansi_chatset = ANSI charset
config.repo.force_private = Force private
config.repo.max_creation_limit = Max creation limit
config.repo.preferred_licenses = Preferred licenses
config.repo.disable_http_git = Disable HTTP Git
config.repo.enable_local_path_migration = Enable local path migration
config.repo.enable_raw_file_render_mode = Enable raw file render mode
config.repo.commits_fetch_concurrency = Commits fetch concurrency
config.repo.editor.line_wrap_extensions = Editor line wrap extensions
config.repo.editor.previewable_file_modes = Editor previewable file modes
config.repo.upload.enabled = Upload enabled
config.repo.upload.temp_path = Upload temporary path
config.repo.upload.allowed_types = Upload allowed types
config.repo.upload.file_max_size = Upload file size limit
config.repo.upload.max_files = Upload files limit
config.log_file_root_path = Log File Root Path
config.reverse_auth_user = Reverse Authentication User
config.repo_config = Repository Configuration
config.repo_root_path = Repository Root Path
config.script_type = Script Type
config.repo_force_private = Force Private
config.max_creation_limit = Max Creation Limit
config.preferred_licenses = Preferred Licenses
config.disable_http_git = Disable HTTP Git
config.enable_local_path_migration = Enable Local Path Migration
config.commits_fetch_concurrency = Commits Fetch Concurrency
config.http_config = HTTP Configuration
config.http_access_control_allow_origin = Access Control Allow Origin

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -119,8 +119,8 @@ func runBackup(c *cli.Context) error {
// Repositories
if !c.Bool("exclude-repos") && !c.Bool("database-only") {
reposDump := filepath.Join(rootDir, "repositories.zip")
log.Info("Dumping repositories in '%s'", conf.RepoRootPath)
if err = zip.PackTo(conf.RepoRootPath, reposDump, true); err != nil {
log.Info("Dumping repositories in %q", conf.Repository.Root)
if err = zip.PackTo(conf.Repository.Root, reposDump, true); err != nil {
log.Fatal("Failed to dump repositories: %v", err)
}
log.Info("Repositories dumped to: %s", reposDump)

View File

@ -145,7 +145,7 @@ func runRestore(c *cli.Context) error {
// Repositories
reposPath := filepath.Join(archivePath, "repositories.zip")
if !c.Bool("exclude-repos") && !c.Bool("database-only") && com.IsExist(reposPath) {
if err := zip.ExtractTo(reposPath, filepath.Dir(conf.RepoRootPath)); err != nil {
if err := zip.ExtractTo(reposPath, filepath.Dir(conf.Repository.Root)); err != nil {
log.Fatal("Failed to extract 'repositories.zip': %v", err)
}
}

View File

@ -267,7 +267,7 @@ func runServ(c *cli.Context) error {
RepoPath: repo.RepoPath(),
})...)
}
gitCmd.Dir = conf.RepoRootPath
gitCmd.Dir = conf.Repository.Root
gitCmd.Stdout = os.Stdout
gitCmd.Stdin = os.Stdin
gitCmd.Stderr = os.Stderr

View File

@ -100,6 +100,7 @@ func Init(customConf string) error {
if err = File.Section("server").MapTo(&Server); err != nil {
return errors.Wrap(err, "mapping [server] section")
}
Server.AppDataPath = ensureAbs(Server.AppDataPath)
if !strings.HasSuffix(Server.ExternalURL, "/") {
Server.ExternalURL += "/"
@ -122,22 +123,19 @@ func Init(customConf string) error {
}
Server.UnixSocketMode = os.FileMode(unixSocketMode)
if !filepath.IsAbs(Server.AppDataPath) {
Server.AppDataPath = filepath.Join(WorkDir(), Server.AppDataPath)
}
// ************************
// ----- SSH settings -----
// ************************
SSH.RootPath = filepath.Join(HomeDir(), ".ssh")
SSH.KeyTestPath = os.TempDir()
if err = File.Section("server").MapTo(&SSH); err != nil {
return errors.Wrap(err, "mapping SSH settings from [server] section")
}
SSH.RootPath = ensureAbs(SSH.RootPath)
SSH.KeyTestPath = ensureAbs(SSH.KeyTestPath)
if !SSH.Disabled {
SSH.RootPath = filepath.Join(HomeDir(), ".ssh")
SSH.KeyTestPath = os.TempDir()
if !SSH.StartBuiltinServer {
if err := os.MkdirAll(SSH.RootPath, 0700); err != nil {
return errors.Wrap(err, "create SSH root directory")
@ -173,7 +171,18 @@ func Init(customConf string) error {
}
}
transferDeprecated()
// *******************************
// ----- Repository settings -----
// *******************************
Repository.Root = filepath.Join(HomeDir(), "gogs-repositories")
if err = File.Section("repository").MapTo(&Repository); err != nil {
return errors.Wrap(err, "mapping [repository] section")
}
Repository.Root = ensureAbs(Repository.Root)
Repository.Upload.TempPath = ensureAbs(Repository.Upload.TempPath)
handleDeprecated()
// TODO
@ -224,27 +233,6 @@ func Init(customConf string) error {
"StampNano": time.StampNano,
}[File.Section("time").Key("FORMAT").MustString("RFC1123")]
// Determine and create root git repository path.
sec = File.Section("repository")
RepoRootPath = sec.Key("ROOT").MustString(filepath.Join(HomeDir(), "gogs-repositories"))
if !filepath.IsAbs(RepoRootPath) {
RepoRootPath = path.Join(workDir, RepoRootPath)
} else {
RepoRootPath = path.Clean(RepoRootPath)
}
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
if err = File.Section("repository").MapTo(&Repository); err != nil {
log.Fatal("Failed to map Repository settings: %v", err)
} else if err = File.Section("repository.editor").MapTo(&Repository.Editor); err != nil {
log.Fatal("Failed to map Repository.Editor settings: %v", err)
} else if err = File.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
log.Fatal("Failed to map Repository.Upload settings: %v", err)
}
if !filepath.IsAbs(Repository.Upload.TempPath) {
Repository.Upload.TempPath = path.Join(workDir, Repository.Upload.TempPath)
}
sec = File.Section("picture")
AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(filepath.Join(Server.AppDataPath, "avatars"))
if !filepath.IsAbs(AvatarUploadPath) {
@ -361,37 +349,6 @@ var (
UsePostgreSQL bool
UseMSSQL bool
// Repository settings
Repository struct {
AnsiCharset string
ForcePrivate bool
MaxCreationLimit int
MirrorQueueLength int
PullRequestQueueLength int
PreferredLicenses []string
DisableHTTPGit bool `ini:"DISABLE_HTTP_GIT"`
EnableLocalPathMigration bool
CommitsFetchConcurrency int
EnableRawFileRenderMode bool
// Repository editor settings
Editor struct {
LineWrapExtensions []string
PreviewableFileModes []string
} `ini:"-"`
// Repository upload settings
Upload struct {
Enabled bool
TempPath string
AllowedTypes []string `delim:"|"`
FileMaxSize int64
MaxFiles int
} `ini:"-"`
}
RepoRootPath string
ScriptType string
// Webhook settings
Webhook struct {
Types []string

View File

@ -12,9 +12,13 @@ import (
// README: This file contains static values that should only be set at initialization time.
// HasMinWinSvc is whether the application is built with Windows Service support.
//
// ⚠️ WARNING: should only be set by "static_minwinsvc.go".
var HasMinWinSvc bool
// Build information should only be set by -ldflags.
// Build time and commit information.
//
// ⚠️ WARNING: should only be set by -ldflags.
var (
BuildTime string
BuildCommit string
@ -28,7 +32,7 @@ var CustomConf string
var (
// Application settings
App struct {
// ⚠️ WARNING: Should only be set by gogs.go.
// ⚠️ WARNING: Should only be set by main package (i.e. "gogs.go").
Version string `ini:"-"`
BrandName string
@ -90,10 +94,39 @@ var (
ListenPort int `ini:"SSH_LISTEN_PORT"`
ServerCiphers []string `ini:"SSH_SERVER_CIPHERS"`
}
// Repository settings
Repository struct {
Root string
ScriptType string
ANSICharset string `ini:"ANSI_CHARSET"`
ForcePrivate bool
MaxCreationLimit int
PreferredLicenses []string
DisableHTTPGit bool `ini:"DISABLE_HTTP_GIT"`
EnableLocalPathMigration bool
EnableRawFileRenderMode bool
CommitsFetchConcurrency int
// Repository editor settings
Editor struct {
LineWrapExtensions []string
PreviewableFileModes []string
} `ini:"repository.editor"`
// Repository upload settings
Upload struct {
Enabled bool
TempPath string
AllowedTypes []string `delim:"|"`
FileMaxSize int64
MaxFiles int
} `ini:"repository.upload"`
}
)
// transferDeprecated transfers deprecated values to the new ones when set.
func transferDeprecated() {
// handleDeprecated transfers deprecated values to the new ones when set.
func handleDeprecated() {
if App.AppName != "" {
App.BrandName = App.AppName
App.AppName = ""

View File

@ -5,6 +5,7 @@
package conf
import (
"path/filepath"
"strings"
"github.com/pkg/errors"
@ -25,3 +26,11 @@ func openSSHVersion() (string, error) {
v = strings.TrimSuffix(strings.TrimPrefix(v, "OpenSSH_"), "p")
return v, nil
}
// ensureAbs prepends the WorkDir to the given path if it is not an absolute path.
func ensureAbs(path string) string {
if filepath.IsAbs(path) {
return path
}
return filepath.Join(WorkDir(), path)
}

View File

@ -32,9 +32,9 @@ func generateAndMigrateGitHooks(x *xorm.Engine) (err error) {
var (
hookNames = []string{"pre-receive", "update", "post-receive"}
hookTpls = []string{
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", conf.ScriptType, conf.AppPath(), conf.CustomConf),
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", conf.ScriptType, conf.AppPath(), conf.CustomConf),
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", conf.ScriptType, conf.AppPath(), conf.CustomConf),
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' pre-receive\n", conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf),
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' update $1 $2 $3\n", conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf),
fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf),
}
)
@ -63,7 +63,7 @@ func generateAndMigrateGitHooks(x *xorm.Engine) (err error) {
return nil
}
repoBase := filepath.Join(conf.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name))
repoBase := filepath.Join(conf.Repository.Root, strings.ToLower(user.Name), strings.ToLower(repo.Name))
repoPath := repoBase + ".git"
wikiPath := repoBase + ".wiki.git"
log.Trace("[%04d]: %s", idx, repoPath)

View File

@ -60,7 +60,7 @@ func updateRepositorySizes(x *xorm.Engine) (err error) {
continue
}
repoPath := filepath.Join(conf.RepoRootPath, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
repoPath := filepath.Join(conf.Repository.Root, strings.ToLower(user.Name), strings.ToLower(repo.Name)) + ".git"
countObject, err := git.GetRepoSize(repoPath)
if err != nil {
log.Warn("GetRepoSize: %v", err)

View File

@ -18,13 +18,13 @@ import (
"github.com/gogs/git-module"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/db/errors"
"gogs.io/gogs/internal/process"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/sync"
)
var MirrorQueue = sync.NewUniqueQueue(conf.Repository.MirrorQueueLength)
var MirrorQueue = sync.NewUniqueQueue(1000)
// Mirror represents mirror information of a repository.
type Mirror struct {

View File

@ -26,7 +26,7 @@ import (
"gogs.io/gogs/internal/sync"
)
var PullRequestQueue = sync.NewUniqueQueue(conf.Repository.PullRequestQueueLength)
var PullRequestQueue = sync.NewUniqueQueue(1000)
type PullRequestType int

View File

@ -857,7 +857,7 @@ func createDelegateHooks(repoPath string) (err error) {
for _, name := range git.HookNames {
hookPath := filepath.Join(repoPath, "hooks", name)
if err = ioutil.WriteFile(hookPath,
[]byte(fmt.Sprintf(hooksTpls[name], conf.ScriptType, conf.AppPath(), conf.CustomConf)),
[]byte(fmt.Sprintf(hooksTpls[name], conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf)),
os.ModePerm); err != nil {
return fmt.Errorf("create delegate hook '%s': %v", hookPath, err)
}

View File

@ -877,7 +877,7 @@ func DeleteInactivateUsers() (err error) {
// UserPath returns the path absolute path of user repositories.
func UserPath(userName string) string {
return filepath.Join(conf.RepoRootPath, strings.ToLower(userName))
return filepath.Join(conf.Repository.Root, strings.ToLower(userName))
}
func GetUserByKeyID(keyID int64) (*User, error) {

View File

@ -199,13 +199,11 @@ func Config(c *context.Context) {
c.Data["App"] = conf.App
c.Data["Server"] = conf.Server
c.Data["SSH"] = conf.SSH
c.Data["Repository"] = conf.Repository
c.Data["LogRootPath"] = conf.LogRootPath
c.Data["ReverseProxyAuthUser"] = conf.ReverseProxyAuthUser
c.Data["RepoRootPath"] = conf.RepoRootPath
c.Data["ScriptType"] = conf.ScriptType
c.Data["Repository"] = conf.Repository
c.Data["HTTP"] = conf.HTTP
c.Data["DbCfg"] = db.DbCfg

View File

@ -155,7 +155,7 @@ func Install(c *context.Context) {
// Application general settings
f.AppName = conf.App.BrandName
f.RepoRootPath = conf.RepoRootPath
f.RepoRootPath = conf.Repository.Root
// Note(unknwon): it's hard for Windows users change a running user,
// so just use current one if config says default.

View File

@ -19,11 +19,11 @@ import (
"gopkg.in/macaron.v1"
log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/db"
"gogs.io/gogs/internal/db/errors"
"gogs.io/gogs/internal/lazyregexp"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/tool"
)
@ -368,7 +368,7 @@ func getGitRepoPath(dir string) (string, error) {
dir += ".git"
}
filename := path.Join(conf.RepoRootPath, dir)
filename := path.Join(conf.Repository.Root, dir)
if _, err := os.Stat(filename); os.IsNotExist(err) {
return "", err
}

View File

@ -62,9 +62,9 @@ func DetectEncoding(content []byte) (string, error) {
}
result, err := chardet.NewTextDetector().DetectBest(content)
if result.Charset != "UTF-8" && len(conf.Repository.AnsiCharset) > 0 {
log.Trace("Using default AnsiCharset: %s", conf.Repository.AnsiCharset)
return conf.Repository.AnsiCharset, err
if result.Charset != "UTF-8" && len(conf.Repository.ANSICharset) > 0 {
log.Trace("Using default ANSICharset: %s", conf.Repository.ANSICharset)
return conf.Repository.ANSICharset, err
}
log.Trace("Detected encoding: %s", result.Charset)

View File

@ -5,6 +5,8 @@
{{template "admin/navbar" .}}
<div class="twelve wide column content">
{{template "base/alert" .}}
{{/* Server settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.server_config"}}
</h4>
@ -70,6 +72,7 @@
</dl>
</div>
{{/* SSH settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.ssh_config"}}
</h4>
@ -109,28 +112,52 @@
</dl>
</div>
<!-- Repository Configuration -->
{{/* Repository settings */}}
<h4 class="ui top attached header">
{{.i18n.Tr "admin.config.repo_config"}}
</h4>
<div class="ui attached table segment">
<dl class="dl-horizontal admin-dl-horizontal">
<dt>{{.i18n.Tr "admin.config.repo_root_path"}}</dt>
<dd><code>{{.RepoRootPath}}</code></dd>
<dt>{{.i18n.Tr "admin.config.script_type"}}</dt>
<dd>{{.ScriptType}}</dd>
<dt>{{.i18n.Tr "admin.config.repo_force_private"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.root_path"}}</dt>
<dd><code>{{.Repository.Root}}</code></dd>
<dt>{{.i18n.Tr "admin.config.repo.script_type"}}</dt>
<dd><code>{{.Repository.ScriptType}}</code></dd>
<dt>{{.i18n.Tr "admin.config.repo.ansi_chatset"}}</dt>
<dd>{{if .Repository.ANSICharset}}{{.Repository.AnsiCharset}}{{else}}{{.i18n.Tr "admin.config.not_set"}}{{end}}</dd>
<dt>{{.i18n.Tr "admin.config.repo.force_private"}}</dt>
<dd><i class="fa fa{{if .Repository.ForcePrivate}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.max_creation_limit"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.max_creation_limit"}}</dt>
<dd>{{.Repository.MaxCreationLimit}}</dd>
<dt>{{.i18n.Tr "admin.config.preferred_licenses"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.preferred_licenses"}}</dt>
<dd>{{Join .Repository.PreferredLicenses ", "}}</dd>
<dt>{{.i18n.Tr "admin.config.disable_http_git"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.disable_http_git"}}</dt>
<dd><i class="fa fa{{if .Repository.DisableHTTPGit}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.enable_local_path_migration"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.enable_local_path_migration"}}</dt>
<dd><i class="fa fa{{if .Repository.EnableLocalPathMigration}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.commits_fetch_concurrency"}}</dt>
<dt>{{.i18n.Tr "admin.config.repo.enable_raw_file_render_mode"}}</dt>
<dd><i class="fa fa{{if .Repository.EnableRawFileRenderMode}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.repo.commits_fetch_concurrency"}}</dt>
<dd>{{.Repository.CommitsFetchConcurrency}}</dd>
<div class="ui divider"></div>
<dt>{{.i18n.Tr "admin.config.repo.editor.line_wrap_extensions"}}</dt>
<dd><code>{{.Repository.Editor.LineWrapExtensions}}</code></dd>
<dt>{{.i18n.Tr "admin.config.repo.editor.previewable_file_modes"}}</dt>
<dd><code>{{.Repository.Editor.PreviewableFileModes}}</code></dd>
<div class="ui divider"></div>
<dt>{{.i18n.Tr "admin.config.repo.upload.enabled"}}</dt>
<dd><i class="fa fa{{if .Repository.Upload.Enabled}}-check{{end}}-square-o"></i></dd>
<dt>{{.i18n.Tr "admin.config.repo.upload.temp_path"}}</dt>
<dd><code>{{.Repository.Upload.TempPath}}</code></dd>
<dt>{{.i18n.Tr "admin.config.repo.upload.allowed_types"}}</dt>
<dd><code>{{.Repository.Upload.AllowedTypes}}</code></dd>
<dt>{{.i18n.Tr "admin.config.repo.upload.file_max_size"}}</dt>
<dd>{{.Repository.Upload.FileMaxSize}} MB</dd>
<dt>{{.i18n.Tr "admin.config.repo.upload.max_files"}}</dt>
<dd>{{.Repository.Upload.MaxFiles}}</dd>
</dl>
</div>