diff options
Diffstat (limited to 'internal/conf/conf.go')
-rw-r--r-- | internal/conf/conf.go | 502 |
1 files changed, 98 insertions, 404 deletions
diff --git a/internal/conf/conf.go b/internal/conf/conf.go index 46133ab8..b708eb83 100644 --- a/internal/conf/conf.go +++ b/internal/conf/conf.go @@ -9,7 +9,6 @@ import ( "net/mail" "net/url" "os" - "path" "path/filepath" "strconv" "strings" @@ -18,13 +17,12 @@ import ( _ "github.com/go-macaron/cache/memcache" _ "github.com/go-macaron/cache/redis" _ "github.com/go-macaron/session/redis" + "github.com/gogs/go-libravatar" "github.com/mcuadros/go-version" "github.com/pkg/errors" "gopkg.in/ini.v1" log "unknwon.dev/clog/v2" - "github.com/gogs/go-libravatar" - "gogs.io/gogs/internal/assets/conf" "gogs.io/gogs/internal/osutil" ) @@ -184,18 +182,18 @@ func Init(customConf string) error { Repository.Root = ensureAbs(Repository.Root) Repository.Upload.TempPath = ensureAbs(Repository.Upload.TempPath) - // ******************************* + // ***************************** // ----- Database settings ----- - // ******************************* + // ***************************** if err = File.Section("database").MapTo(&Database); err != nil { return errors.Wrap(err, "mapping [database] section") } Database.Path = ensureAbs(Database.Path) - // ******************************* + // ***************************** // ----- Security settings ----- - // ******************************* + // ***************************** if err = File.Section("security").MapTo(&Security); err != nil { return errors.Wrap(err, "mapping [security] section") @@ -245,37 +243,40 @@ func Init(customConf string) error { return errors.Wrap(err, "mapping [service] section") } - // *********************************** + // ************************* // ----- User settings ----- - // *********************************** + // ************************* if err = File.Section("user").MapTo(&User); err != nil { return errors.Wrap(err, "mapping [user] section") } - // *********************************** + // **************************** // ----- Session settings ----- - // *********************************** + // **************************** if err = File.Section("session").MapTo(&Session); err != nil { return errors.Wrap(err, "mapping [session] section") } - handleDeprecated() + // ******************************* + // ----- Attachment settings ----- + // ******************************* + + if err = File.Section("attachment").MapTo(&Attachment); err != nil { + return errors.Wrap(err, "mapping [attachment] section") + } + Attachment.Path = ensureAbs(Attachment.Path) - // TODO + // ************************* + // ----- Time settings ----- + // ************************* - sec := File.Section("attachment") - AttachmentPath = sec.Key("PATH").MustString(filepath.Join(Server.AppDataPath, "attachments")) - if !filepath.IsAbs(AttachmentPath) { - AttachmentPath = path.Join(workDir, AttachmentPath) + if err = File.Section("time").MapTo(&Time); err != nil { + return errors.Wrap(err, "mapping [time] section") } - AttachmentAllowedTypes = strings.Replace(sec.Key("ALLOWED_TYPES").MustString("image/jpeg,image/png"), "|", ",", -1) - AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(4) - AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5) - AttachmentEnabled = sec.Key("ENABLED").MustBool(true) - TimeFormat = map[string]string{ + Time.FormatLayout = map[string]string{ "ANSIC": time.ANSIC, "UnixDate": time.UnixDate, "RubyDate": time.RubyDate, @@ -291,89 +292,104 @@ func Init(customConf string) error { "StampMilli": time.StampMilli, "StampMicro": time.StampMicro, "StampNano": time.StampNano, - }[File.Section("time").Key("FORMAT").MustString("RFC1123")] - - sec = File.Section("picture") - AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(filepath.Join(Server.AppDataPath, "avatars")) - if !filepath.IsAbs(AvatarUploadPath) { - AvatarUploadPath = path.Join(workDir, AvatarUploadPath) + }[Time.Format] + if Time.FormatLayout == "" { + return fmt.Errorf("unrecognized '[time] FORMAT': %s", Time.Format) } - RepositoryAvatarUploadPath = sec.Key("REPOSITORY_AVATAR_UPLOAD_PATH").MustString(filepath.Join(Server.AppDataPath, "repo-avatars")) - if !filepath.IsAbs(RepositoryAvatarUploadPath) { - RepositoryAvatarUploadPath = path.Join(workDir, RepositoryAvatarUploadPath) + + // **************************** + // ----- Picture settings ----- + // **************************** + + if err = File.Section("picture").MapTo(&Picture); err != nil { + return errors.Wrap(err, "mapping [picture] section") } - switch source := sec.Key("GRAVATAR_SOURCE").MustString("gravatar"); source { - case "duoshuo": - GravatarSource = "http://gravatar.duoshuo.com/avatar/" + Picture.AvatarUploadPath = ensureAbs(Picture.AvatarUploadPath) + Picture.RepositoryAvatarUploadPath = ensureAbs(Picture.RepositoryAvatarUploadPath) + + switch Picture.GravatarSource { case "gravatar": - GravatarSource = "https://secure.gravatar.com/avatar/" + Picture.GravatarSource = "https://secure.gravatar.com/avatar/" case "libravatar": - GravatarSource = "https://seccdn.libravatar.org/avatar/" - default: - GravatarSource = source + Picture.GravatarSource = "https://seccdn.libravatar.org/avatar/" } - DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool() - EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool(true) + if Server.OfflineMode { - DisableGravatar = true - EnableFederatedAvatar = false + Picture.DisableGravatar = true + Picture.EnableFederatedAvatar = false } - if DisableGravatar { - EnableFederatedAvatar = false + if Picture.DisableGravatar { + Picture.EnableFederatedAvatar = false } + if Picture.EnableFederatedAvatar { + gravatarURL, err := url.Parse(Picture.GravatarSource) + if err != nil { + return errors.Wrapf(err, "parse Gravatar source %q", Picture.GravatarSource) + } - if EnableFederatedAvatar { - LibravatarService = libravatar.New() - parts := strings.Split(GravatarSource, "/") - if len(parts) >= 3 { - if parts[0] == "https:" { - LibravatarService.SetUseHTTPS(true) - LibravatarService.SetSecureFallbackHost(parts[2]) - } else { - LibravatarService.SetUseHTTPS(false) - LibravatarService.SetFallbackHost(parts[2]) - } + Picture.LibravatarService = libravatar.New() + if gravatarURL.Scheme == "https" { + Picture.LibravatarService.SetUseHTTPS(true) + Picture.LibravatarService.SetSecureFallbackHost(gravatarURL.Host) + } else { + Picture.LibravatarService.SetUseHTTPS(false) + Picture.LibravatarService.SetFallbackHost(gravatarURL.Host) } } - if err = File.Section("http").MapTo(&HTTP); err != nil { - log.Fatal("Failed to map HTTP settings: %v", err) + // *************************** + // ----- Mirror settings ----- + // *************************** + + if err = File.Section("mirror").MapTo(&Mirror); err != nil { + return errors.Wrap(err, "mapping [mirror] section") + } + + if Mirror.DefaultInterval <= 0 { + Mirror.DefaultInterval = 8 + } + + // ************************* + // ----- I18n settings ----- + // ************************* + + I18n = new(i18n) + if err = File.Section("i18n").MapTo(I18n); err != nil { + return errors.Wrap(err, "mapping [i18n] section") + } + I18n.dateLangs = File.Section("i18n.datelang").KeysHash() + + handleDeprecated() + + if err = File.Section("cache").MapTo(&Cache); err != nil { + return errors.Wrap(err, "mapping [cache] section") + } else if err = File.Section("http").MapTo(&HTTP); err != nil { + return errors.Wrap(err, "mapping [http] section") + } else if err = File.Section("release").MapTo(&Release); err != nil { + return errors.Wrap(err, "mapping [release] section") } else if err = File.Section("webhook").MapTo(&Webhook); err != nil { - log.Fatal("Failed to map Webhook settings: %v", err) - } else if err = File.Section("release.attachment").MapTo(&Release.Attachment); err != nil { - log.Fatal("Failed to map Release.Attachment settings: %v", err) + return errors.Wrap(err, "mapping [webhook] section") } else if err = File.Section("markdown").MapTo(&Markdown); err != nil { - log.Fatal("Failed to map Markdown settings: %v", err) + return errors.Wrap(err, "mapping [markdown] section") } else if err = File.Section("smartypants").MapTo(&Smartypants); err != nil { - log.Fatal("Failed to map Smartypants settings: %v", err) + return errors.Wrap(err, "mapping [smartypants] section") } else if err = File.Section("admin").MapTo(&Admin); err != nil { - log.Fatal("Failed to map Admin settings: %v", err) + return errors.Wrap(err, "mapping [admin] section") } else if err = File.Section("cron").MapTo(&Cron); err != nil { - log.Fatal("Failed to map Cron settings: %v", err) + return errors.Wrap(err, "mapping [cron] section") } else if err = File.Section("git").MapTo(&Git); err != nil { - log.Fatal("Failed to map Git settings: %v", err) - } else if err = File.Section("mirror").MapTo(&Mirror); err != nil { - log.Fatal("Failed to map Mirror settings: %v", err) + return errors.Wrap(err, "mapping [git] section") } else if err = File.Section("api").MapTo(&API); err != nil { - log.Fatal("Failed to map API settings: %v", err) + return errors.Wrap(err, "mapping [api] section") } else if err = File.Section("ui").MapTo(&UI); err != nil { - log.Fatal("Failed to map UI settings: %v", err) + return errors.Wrap(err, "mapping [ui] section") } else if err = File.Section("prometheus").MapTo(&Prometheus); err != nil { - log.Fatal("Failed to map Prometheus settings: %v", err) + return errors.Wrap(err, "mapping [prometheus] section") + } else if err = File.Section("other").MapTo(&Other); err != nil { + return errors.Wrap(err, "mapping [other] section") } - if Mirror.DefaultInterval <= 0 { - Mirror.DefaultInterval = 24 - } - - Langs = File.Section("i18n").Key("LANGS").Strings(",") - Names = File.Section("i18n").Key("NAMES").Strings(",") - dateLangs = File.Section("i18n.datelang").KeysHash() - - ShowFooterBranding = File.Section("other").Key("SHOW_FOOTER_BRANDING").MustBool() - ShowFooterTemplateLoadTime = File.Section("other").Key("SHOW_FOOTER_TEMPLATE_LOAD_TIME").MustBool() - - HasRobotsTxt = osutil.IsFile(path.Join(CustomDir(), "robots.txt")) + HasRobotsTxt = osutil.IsFile(filepath.Join(CustomDir(), "robots.txt")) return nil } @@ -384,325 +400,3 @@ func MustInit(customConf string) { panic(err) } } - -// TODO - -var ( - HTTP struct { - AccessControlAllowOrigin string - } - - // Database settings - UseSQLite3 bool - UseMySQL bool - UsePostgreSQL bool - UseMSSQL bool - - // Webhook settings - Webhook struct { - Types []string - QueueLength int - DeliverTimeout int - SkipTLSVerify bool `ini:"SKIP_TLS_VERIFY"` - PagingNum int - } - - // Release settigns - Release struct { - Attachment struct { - Enabled bool - TempPath string - AllowedTypes []string `delim:"|"` - MaxSize int64 - MaxFiles int - } `ini:"-"` - } - - // Markdown sttings - Markdown struct { - EnableHardLineBreak bool - CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"` - FileExtensions []string - } - - // Smartypants settings - Smartypants struct { - Enabled bool - Fractions bool - Dashes bool - LatexDashes bool - AngledQuotes bool - } - - // Admin settings - Admin struct { - DisableRegularOrgCreation bool - } - - // Picture settings - AvatarUploadPath string - RepositoryAvatarUploadPath string - GravatarSource string - DisableGravatar bool - EnableFederatedAvatar bool - LibravatarService *libravatar.Libravatar - - // Log settings - LogRootPath string - LogModes []string - LogConfigs []interface{} - - // Attachment settings - AttachmentPath string - AttachmentAllowedTypes string - AttachmentMaxSize int64 - AttachmentMaxFiles int - AttachmentEnabled bool - - // Time settings - TimeFormat string - - // Cache settings - CacheAdapter string - CacheInterval int - CacheConn string - - // Cron tasks - Cron struct { - UpdateMirror struct { - Enabled bool - RunAtStart bool - Schedule string - } `ini:"cron.update_mirrors"` - RepoHealthCheck struct { - Enabled bool - RunAtStart bool - Schedule string - Timeout time.Duration - Args []string `delim:" "` - } `ini:"cron.repo_health_check"` - CheckRepoStats struct { - Enabled bool - RunAtStart bool - Schedule string - } `ini:"cron.check_repo_stats"` - RepoArchiveCleanup struct { - Enabled bool - RunAtStart bool - Schedule string - OlderThan time.Duration - } `ini:"cron.repo_archive_cleanup"` - } - - // Git settings - Git struct { - Version string `ini:"-"` - DisableDiffHighlight bool - MaxGitDiffLines int - MaxGitDiffLineCharacters int - MaxGitDiffFiles int - GCArgs []string `ini:"GC_ARGS" delim:" "` - Timeout struct { - Migrate int - Mirror int - Clone int - Pull int - GC int `ini:"GC"` - } `ini:"git.timeout"` - } - - // Mirror settings - Mirror struct { - DefaultInterval int - } - - // API settings - API struct { - MaxResponseItems int - } - - // UI settings - UI struct { - ExplorePagingNum int - IssuePagingNum int - FeedMaxCommitNum int - ThemeColorMetaTag string - MaxDisplayFileSize int64 - - Admin struct { - UserPagingNum int - RepoPagingNum int - NoticePagingNum int - OrgPagingNum int - } `ini:"ui.admin"` - User struct { - RepoPagingNum int - NewsFeedPagingNum int - CommitsPagingNum int - } `ini:"ui.user"` - } - - // Prometheus settings - Prometheus struct { - Enabled bool - EnableBasicAuth bool - BasicAuthUsername string - BasicAuthPassword string - } - - // I18n settings - Langs []string - Names []string - dateLangs map[string]string - - // Highlight settings are loaded in modules/template/hightlight.go - - // Other settings - ShowFooterBranding bool - ShowFooterTemplateLoadTime bool - - // Global setting objects - HasRobotsTxt bool -) - -// DateLang transforms standard language locale name to corresponding value in datetime plugin. -func DateLang(lang string) string { - name, ok := dateLangs[lang] - if ok { - return name - } - return "en" -} - -// InitLogging initializes the logging service of the application. -func InitLogging() { - LogRootPath = File.Section("log").Key("ROOT_PATH").MustString(filepath.Join(WorkDir(), "log")) - - // Because we always create a console logger as the primary logger at init time, - // we need to remove it in case the user doesn't configure to use it after the - // logging service is initalized. - hasConsole := false - - // Iterate over [log.*] sections to initialize individual logger. - LogModes = strings.Split(File.Section("log").Key("MODE").MustString("console"), ",") - LogConfigs = make([]interface{}, len(LogModes)) - levelMappings := map[string]log.Level{ - "trace": log.LevelTrace, - "info": log.LevelInfo, - "warn": log.LevelWarn, - "error": log.LevelError, - "fatal": log.LevelFatal, - } - - type config struct { - Buffer int64 - Config interface{} - } - for i, mode := range LogModes { - mode = strings.ToLower(strings.TrimSpace(mode)) - secName := "log." + mode - sec, err := File.GetSection(secName) - if err != nil { - log.Fatal("Missing configuration section [%s] for %q logger", secName, mode) - return - } - - level := levelMappings[strings.ToLower(sec.Key("LEVEL").MustString("trace"))] - buffer := sec.Key("BUFFER_LEN").MustInt64(100) - c := new(config) - switch mode { - case log.DefaultConsoleName: - hasConsole = true - c = &config{ - Buffer: buffer, - Config: log.ConsoleConfig{ - Level: level, - }, - } - err = log.NewConsole(c.Buffer, c.Config) - - case log.DefaultFileName: - logPath := filepath.Join(LogRootPath, "gogs.log") - logDir := filepath.Dir(logPath) - err = os.MkdirAll(logDir, os.ModePerm) - if err != nil { - log.Fatal("Failed to create log directory %q: %v", logDir, err) - return - } - - c = &config{ - Buffer: buffer, - Config: log.FileConfig{ - Level: level, - Filename: logPath, - FileRotationConfig: log.FileRotationConfig{ - Rotate: sec.Key("LOG_ROTATE").MustBool(true), - Daily: sec.Key("DAILY_ROTATE").MustBool(true), - MaxSize: 1 << uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)), - MaxLines: sec.Key("MAX_LINES").MustInt64(1000000), - MaxDays: sec.Key("MAX_DAYS").MustInt64(7), - }, - }, - } - err = log.NewFile(c.Buffer, c.Config) - - case log.DefaultSlackName: - c = &config{ - Buffer: buffer, - Config: log.SlackConfig{ - Level: level, - URL: sec.Key("URL").String(), - }, - } - err = log.NewSlack(c.Buffer, c.Config) - - case log.DefaultDiscordName: - c = &config{ - Buffer: buffer, - Config: log.DiscordConfig{ - Level: level, - URL: sec.Key("URL").String(), - Username: sec.Key("USERNAME").String(), - }, - } - - default: - continue - } - - if err != nil { - log.Fatal("Failed to init %s logger: %v", mode, err) - return - } - LogConfigs[i] = c - - log.Trace("Log mode: %s (%s)", strings.Title(mode), strings.Title(strings.ToLower(level.String()))) - } - - if !hasConsole { - log.Remove(log.DefaultConsoleName) - } -} - -func newCacheService() { - CacheAdapter = File.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"}) - switch CacheAdapter { - case "memory": - CacheInterval = File.Section("cache").Key("INTERVAL").MustInt(60) - case "redis", "memcache": - CacheConn = strings.Trim(File.Section("cache").Key("HOST").String(), "\" ") - default: - log.Fatal("Unrecognized cache adapter %q", CacheAdapter) - return - } - - log.Trace("Cache service is enabled") -} - -func NewServices() { - newCacheService() -} - -// HookMode indicates whether program starts as Git server-side hook callback. -// All operations should be done synchronously to prevent program exits before finishing. -var HookMode bool |