Add gitea manager reload-templates command (#24843)

This can be useful to update custom templates in production mode, when
they are updated frequently and a full Gitea restart each time is
disruptive.
This commit is contained in:
Brecht Van Lommel 2023-05-22 17:51:40 +02:00 committed by GitHub
parent 922c83eea3
commit 3588edbb08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 3 deletions

View file

@ -21,6 +21,7 @@ var (
Subcommands: []cli.Command{ Subcommands: []cli.Command{
subcmdShutdown, subcmdShutdown,
subcmdRestart, subcmdRestart,
subcmdReloadTemplates,
subcmdFlushQueues, subcmdFlushQueues,
subcmdLogging, subcmdLogging,
subCmdProcesses, subCmdProcesses,
@ -46,6 +47,16 @@ var (
}, },
Action: runRestart, Action: runRestart,
} }
subcmdReloadTemplates = cli.Command{
Name: "reload-templates",
Usage: "Reload template files in the running process",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "debug",
},
},
Action: runReloadTemplates,
}
subcmdFlushQueues = cli.Command{ subcmdFlushQueues = cli.Command{
Name: "flush-queues", Name: "flush-queues",
Usage: "Flush queues in the running process", Usage: "Flush queues in the running process",
@ -115,6 +126,15 @@ func runRestart(c *cli.Context) error {
return handleCliResponseExtra(extra) return handleCliResponseExtra(extra)
} }
func runReloadTemplates(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
setup(ctx, c.Bool("debug"))
extra := private.ReloadTemplates(ctx)
return handleCliResponseExtra(extra)
}
func runFlushQueues(c *cli.Context) error { func runFlushQueues(c *cli.Context) error {
ctx, cancel := installSignals() ctx, cancel := installSignals()
defer cancel() defer cancel()

View file

@ -29,6 +29,13 @@ func Restart(ctx context.Context) ResponseExtra {
return requestJSONClientMsg(req, "Restarting") return requestJSONClientMsg(req, "Restarting")
} }
// ReloadTemplates calls the internal reload-templates function
func ReloadTemplates(ctx context.Context) ResponseExtra {
reqURL := setting.LocalURL + "api/internal/manager/reload-templates"
req := newInternalRequest(ctx, reqURL, "POST")
return requestJSONClientMsg(req, "Reloaded")
}
// FlushOptions represents the options for the flush call // FlushOptions represents the options for the flush call
type FlushOptions struct { type FlushOptions struct {
Timeout time.Duration Timeout time.Duration

View file

@ -96,6 +96,14 @@ func HTMLRenderer() *HTMLRender {
return htmlRender return htmlRender
} }
func ReloadHTMLTemplates() error {
if err := htmlRender.CompileTemplates(); err != nil {
log.Error("Template error: %v\n%s", err, log.Stack(2))
return err
}
return nil
}
func initHTMLRenderer() { func initHTMLRenderer() {
rendererType := "static" rendererType := "static"
if !setting.IsProd { if !setting.IsProd {
@ -115,9 +123,7 @@ func initHTMLRenderer() {
if !setting.IsProd { if !setting.IsProd {
go AssetFS().WatchLocalChanges(graceful.GetManager().ShutdownContext(), func() { go AssetFS().WatchLocalChanges(graceful.GetManager().ShutdownContext(), func() {
if err := htmlRender.CompileTemplates(); err != nil { _ = ReloadHTMLTemplates()
log.Error("Template error: %v\n%s", err, log.Stack(2))
}
}) })
} }
} }

View file

@ -67,6 +67,7 @@ func Routes() *web.Route {
r.Get("/serv/command/{keyid}/{owner}/{repo}", ServCommand) r.Get("/serv/command/{keyid}/{owner}/{repo}", ServCommand)
r.Post("/manager/shutdown", Shutdown) r.Post("/manager/shutdown", Shutdown)
r.Post("/manager/restart", Restart) r.Post("/manager/restart", Restart)
r.Post("/manager/reload-templates", ReloadTemplates)
r.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) r.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues)
r.Post("/manager/pause-logging", PauseLogging) r.Post("/manager/pause-logging", PauseLogging)
r.Post("/manager/resume-logging", ResumeLogging) r.Post("/manager/resume-logging", ResumeLogging)

View file

@ -15,9 +15,22 @@ import (
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
) )
// ReloadTemplates reloads all the templates
func ReloadTemplates(ctx *context.PrivateContext) {
err := templates.ReloadHTMLTemplates()
if err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{
UserMsg: fmt.Sprintf("Template error: %v", err),
})
return
}
ctx.PlainText(http.StatusOK, "success")
}
// FlushQueues flushes all the Queues // FlushQueues flushes all the Queues
func FlushQueues(ctx *context.PrivateContext) { func FlushQueues(ctx *context.PrivateContext) {
opts := web.GetForm(ctx).(*private.FlushOptions) opts := web.GetForm(ctx).(*private.FlushOptions)