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.tags/v1.20.0-rc0
@@ -21,6 +21,7 @@ var ( | |||
Subcommands: []cli.Command{ | |||
subcmdShutdown, | |||
subcmdRestart, | |||
subcmdReloadTemplates, | |||
subcmdFlushQueues, | |||
subcmdLogging, | |||
subCmdProcesses, | |||
@@ -46,6 +47,16 @@ var ( | |||
}, | |||
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{ | |||
Name: "flush-queues", | |||
Usage: "Flush queues in the running process", | |||
@@ -115,6 +126,15 @@ func runRestart(c *cli.Context) error { | |||
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 { | |||
ctx, cancel := installSignals() | |||
defer cancel() |
@@ -29,6 +29,13 @@ func Restart(ctx context.Context) ResponseExtra { | |||
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 | |||
type FlushOptions struct { | |||
Timeout time.Duration |
@@ -96,6 +96,14 @@ func HTMLRenderer() *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() { | |||
rendererType := "static" | |||
if !setting.IsProd { | |||
@@ -115,9 +123,7 @@ func initHTMLRenderer() { | |||
if !setting.IsProd { | |||
go AssetFS().WatchLocalChanges(graceful.GetManager().ShutdownContext(), func() { | |||
if err := htmlRender.CompileTemplates(); err != nil { | |||
log.Error("Template error: %v\n%s", err, log.Stack(2)) | |||
} | |||
_ = ReloadHTMLTemplates() | |||
}) | |||
} | |||
} |
@@ -67,6 +67,7 @@ func Routes() *web.Route { | |||
r.Get("/serv/command/{keyid}/{owner}/{repo}", ServCommand) | |||
r.Post("/manager/shutdown", Shutdown) | |||
r.Post("/manager/restart", Restart) | |||
r.Post("/manager/reload-templates", ReloadTemplates) | |||
r.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) | |||
r.Post("/manager/pause-logging", PauseLogging) | |||
r.Post("/manager/resume-logging", ResumeLogging) |
@@ -15,9 +15,22 @@ import ( | |||
"code.gitea.io/gitea/modules/private" | |||
"code.gitea.io/gitea/modules/queue" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/templates" | |||
"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 | |||
func FlushQueues(ctx *context.PrivateContext) { | |||
opts := web.GetForm(ctx).(*private.FlushOptions) |