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:
		
							parent
							
								
									922c83eea3
								
							
						
					
					
						commit
						3588edbb08
					
				| 
						 | 
					@ -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()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue