f8e93ce423
Even if the log mode is `file`, there are still few logs printed to the console at the very beginning. That's fine but confusing. Someone will think the console is the only place to find logs, and get nothing helpful. See https://github.com/go-gitea/gitea/issues/22274#issuecomment-1367917717. There should be a reminder that there are no more logs to the console. And to avoid log loss, we should add configured loggers first, then remove console logger if there's no `console` in the mode. Tests with `MODE = file`: Before: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/210079862-d591677f-347e-46ed-a548-bb2ddbb0885c.png"> After: <img width="1792" alt="image" src="https://user-images.githubusercontent.com/9418365/210080002-d66cc418-6888-4909-b370-d03f5986ef41.png"> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: delvh <dev.lh@web.de>
200 lines
5.9 KiB
Go
200 lines
5.9 KiB
Go
// Copyright 2016 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package routers
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"runtime"
|
|
|
|
"code.gitea.io/gitea/models"
|
|
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
|
"code.gitea.io/gitea/modules/cache"
|
|
"code.gitea.io/gitea/modules/eventsource"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/highlight"
|
|
code_indexer "code.gitea.io/gitea/modules/indexer/code"
|
|
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
|
|
stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/markup"
|
|
"code.gitea.io/gitea/modules/markup/external"
|
|
"code.gitea.io/gitea/modules/notification"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/ssh"
|
|
"code.gitea.io/gitea/modules/storage"
|
|
"code.gitea.io/gitea/modules/svg"
|
|
"code.gitea.io/gitea/modules/system"
|
|
"code.gitea.io/gitea/modules/templates"
|
|
"code.gitea.io/gitea/modules/translation"
|
|
"code.gitea.io/gitea/modules/util"
|
|
"code.gitea.io/gitea/modules/web"
|
|
packages_router "code.gitea.io/gitea/routers/api/packages"
|
|
apiv1 "code.gitea.io/gitea/routers/api/v1"
|
|
"code.gitea.io/gitea/routers/common"
|
|
"code.gitea.io/gitea/routers/private"
|
|
web_routers "code.gitea.io/gitea/routers/web"
|
|
"code.gitea.io/gitea/services/auth"
|
|
"code.gitea.io/gitea/services/auth/source/oauth2"
|
|
"code.gitea.io/gitea/services/automerge"
|
|
"code.gitea.io/gitea/services/cron"
|
|
"code.gitea.io/gitea/services/mailer"
|
|
markup_service "code.gitea.io/gitea/services/markup"
|
|
repo_migrations "code.gitea.io/gitea/services/migrations"
|
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
|
pull_service "code.gitea.io/gitea/services/pull"
|
|
repo_service "code.gitea.io/gitea/services/repository"
|
|
"code.gitea.io/gitea/services/repository/archiver"
|
|
"code.gitea.io/gitea/services/task"
|
|
"code.gitea.io/gitea/services/webhook"
|
|
)
|
|
|
|
func mustInit(fn func() error) {
|
|
err := fn()
|
|
if err != nil {
|
|
ptr := reflect.ValueOf(fn).Pointer()
|
|
fi := runtime.FuncForPC(ptr)
|
|
log.Fatal("%s failed: %v", fi.Name(), err)
|
|
}
|
|
}
|
|
|
|
func mustInitCtx(ctx context.Context, fn func(ctx context.Context) error) {
|
|
err := fn(ctx)
|
|
if err != nil {
|
|
ptr := reflect.ValueOf(fn).Pointer()
|
|
fi := runtime.FuncForPC(ptr)
|
|
log.Fatal("%s(ctx) failed: %v", fi.Name(), err)
|
|
}
|
|
}
|
|
|
|
// InitGitServices init new services for git, this is also called in `contrib/pr/checkout.go`
|
|
func InitGitServices() {
|
|
setting.NewServices()
|
|
mustInit(storage.Init)
|
|
mustInit(repo_service.Init)
|
|
}
|
|
|
|
func syncAppConfForGit(ctx context.Context) error {
|
|
runtimeState := new(system.RuntimeState)
|
|
if err := system.AppState.Get(runtimeState); err != nil {
|
|
return err
|
|
}
|
|
|
|
updated := false
|
|
if runtimeState.LastAppPath != setting.AppPath {
|
|
log.Info("AppPath changed from '%s' to '%s'", runtimeState.LastAppPath, setting.AppPath)
|
|
runtimeState.LastAppPath = setting.AppPath
|
|
updated = true
|
|
}
|
|
if runtimeState.LastCustomConf != setting.CustomConf {
|
|
log.Info("CustomConf changed from '%s' to '%s'", runtimeState.LastCustomConf, setting.CustomConf)
|
|
runtimeState.LastCustomConf = setting.CustomConf
|
|
updated = true
|
|
}
|
|
|
|
if updated {
|
|
log.Info("re-sync repository hooks ...")
|
|
mustInitCtx(ctx, repo_service.SyncRepositoryHooks)
|
|
|
|
log.Info("re-write ssh public keys ...")
|
|
mustInit(asymkey_model.RewriteAllPublicKeys)
|
|
|
|
return system.AppState.Set(runtimeState)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GlobalInitInstalled is for global installed configuration.
|
|
func GlobalInitInstalled(ctx context.Context) {
|
|
if !setting.InstallLock {
|
|
log.Fatal("Gitea is not installed")
|
|
}
|
|
|
|
mustInitCtx(ctx, git.InitFull)
|
|
log.Info("Git Version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
|
|
log.Info("AppPath: %s", setting.AppPath)
|
|
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
|
log.Info("Custom path: %s", setting.CustomPath)
|
|
log.Info("Log path: %s", setting.LogRootPath)
|
|
log.Info("Configuration file: %s", setting.CustomConf)
|
|
log.Info("Run Mode: %s", util.ToTitleCase(setting.RunMode))
|
|
log.Info("Gitea v%s%s", setting.AppVer, setting.AppBuiltWith)
|
|
|
|
// Setup i18n
|
|
translation.InitLocales(ctx)
|
|
|
|
setting.NewServices()
|
|
mustInit(storage.Init)
|
|
|
|
mailer.NewContext(ctx)
|
|
mustInit(cache.NewContext)
|
|
notification.NewContext()
|
|
mustInit(archiver.Init)
|
|
|
|
highlight.NewContext()
|
|
external.RegisterRenderers()
|
|
markup.Init(markup_service.ProcessorHelper())
|
|
|
|
if setting.EnableSQLite3 {
|
|
log.Info("SQLite3 support is enabled")
|
|
} else if setting.Database.UseSQLite3 {
|
|
log.Fatal("SQLite3 support is disabled, but it is used for database setting. Please get or build a Gitea release with SQLite3 support.")
|
|
}
|
|
|
|
mustInitCtx(ctx, common.InitDBEngine)
|
|
log.Info("ORM engine initialization successful!")
|
|
mustInit(system.Init)
|
|
mustInit(oauth2.Init)
|
|
|
|
mustInit(models.Init)
|
|
mustInit(repo_service.Init)
|
|
|
|
// Booting long running goroutines.
|
|
issue_indexer.InitIssueIndexer(false)
|
|
code_indexer.Init()
|
|
mustInit(stats_indexer.Init)
|
|
|
|
mirror_service.InitSyncMirrors()
|
|
mustInit(webhook.Init)
|
|
mustInit(pull_service.Init)
|
|
mustInit(automerge.Init)
|
|
mustInit(task.Init)
|
|
mustInit(repo_migrations.Init)
|
|
eventsource.GetManager().Init()
|
|
|
|
mustInitCtx(ctx, syncAppConfForGit)
|
|
|
|
mustInit(ssh.Init)
|
|
|
|
auth.Init()
|
|
svg.Init()
|
|
|
|
// Finally start up the cron
|
|
cron.NewContext(ctx)
|
|
}
|
|
|
|
// NormalRoutes represents non install routes
|
|
func NormalRoutes(ctx context.Context) *web.Route {
|
|
ctx, _ = templates.HTMLRenderer(ctx)
|
|
r := web.NewRoute()
|
|
for _, middle := range common.Middlewares() {
|
|
r.Use(middle)
|
|
}
|
|
|
|
r.Mount("/", web_routers.Routes(ctx))
|
|
r.Mount("/api/v1", apiv1.Routes(ctx))
|
|
r.Mount("/api/internal", private.Routes())
|
|
|
|
if setting.Packages.Enabled {
|
|
// Add endpoints to match common package manager APIs
|
|
|
|
// This implements package support for most package managers
|
|
r.Mount("/api/packages", packages_router.CommonRoutes(ctx))
|
|
|
|
// This implements the OCI API (Note this is not preceded by /api but is instead /v2)
|
|
r.Mount("/v2", packages_router.ContainerRoutes(ctx))
|
|
}
|
|
return r
|
|
}
|