From de4959fe7b7a6a1ab7a7a12462222efe95fbb661 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Fri, 1 Mar 2024 19:00:29 +0300 Subject: [PATCH 1/3] cmd: fix the output of the `Usage` section (#6138) --- cmd/cobra.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cobra.go b/cmd/cobra.go index d43b43729064..1a2509206a81 100644 --- a/cmd/cobra.go +++ b/cmd/cobra.go @@ -117,7 +117,7 @@ func onlyVersionText() string { func caddyCmdToCobra(caddyCmd Command) *cobra.Command { cmd := &cobra.Command{ - Use: caddyCmd.Name, + Use: caddyCmd.Name + " " + caddyCmd.Usage, Short: caddyCmd.Short, Long: caddyCmd.Long, } From 46c5db92da8ff971db26a3f11282fba5594a7f28 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Fri, 1 Mar 2024 09:57:05 -0700 Subject: [PATCH 2/3] core: OnExit hooks (#6128) * core: OnExit callbacks * core: Process-global OnExit callbacks --- caddy.go | 28 ++++++++++++++++++++++++++++ context.go | 15 +++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/caddy.go b/caddy.go index 92a1fdf2f743..1e0eacd2b07f 100644 --- a/caddy.go +++ b/caddy.go @@ -715,6 +715,7 @@ func exitProcess(ctx context.Context, logger *zap.Logger) { logger.Warn("exiting; byeee!! 👋") exitCode := ExitCodeSuccess + lastContext := ActiveContext() // stop all apps if err := Stop(); err != nil { @@ -736,6 +737,16 @@ func exitProcess(ctx context.Context, logger *zap.Logger) { } } + // execute any process-exit callbacks + for _, exitFunc := range lastContext.exitFuncs { + exitFunc(ctx) + } + exitFuncsMu.Lock() + for _, exitFunc := range exitFuncs { + exitFunc(ctx) + } + exitFuncsMu.Unlock() + // shut down admin endpoint(s) in goroutines so that // if this function was called from an admin handler, // it has a chance to return gracefully @@ -774,6 +785,23 @@ var exiting = new(int32) // accessed atomically // EXPERIMENTAL API: subject to change or removal. func Exiting() bool { return atomic.LoadInt32(exiting) == 1 } +// OnExit registers a callback to invoke during process exit. +// This registration is PROCESS-GLOBAL, meaning that each +// function should only be registered once forever, NOT once +// per config load (etc). +// +// EXPERIMENTAL API: subject to change or removal. +func OnExit(f func(context.Context)) { + exitFuncsMu.Lock() + exitFuncs = append(exitFuncs, f) + exitFuncsMu.Unlock() +} + +var ( + exitFuncs []func(context.Context) + exitFuncsMu sync.Mutex +) + // Duration can be an integer or a string. An integer is // interpreted as nanoseconds. If a string, it is a Go // time.Duration value such as `300ms`, `1.5h`, or `2h45m`; diff --git a/context.go b/context.go index e90475b19d16..d73af770285d 100644 --- a/context.go +++ b/context.go @@ -44,8 +44,9 @@ type Context struct { moduleInstances map[string][]Module cfg *Config - cleanupFuncs []func() ancestry []Module + cleanupFuncs []func() // invoked at every config unload + exitFuncs []func(context.Context) // invoked at config unload ONLY IF the process is exiting (EXPERIMENTAL) } // NewContext provides a new context derived from the given @@ -86,7 +87,8 @@ func (ctx *Context) OnCancel(f func()) { ctx.cleanupFuncs = append(ctx.cleanupFuncs, f) } -// Filesystems returns a ref to the FilesystemMap +// Filesystems returns a ref to the FilesystemMap. +// EXPERIMENTAL: This API is subject to change. func (ctx *Context) Filesystems() FileSystems { // if no config is loaded, we use a default filesystemmap, which includes the osfs if ctx.cfg == nil { @@ -95,6 +97,15 @@ func (ctx *Context) Filesystems() FileSystems { return ctx.cfg.filesystems } +// OnExit executes f when the process exits gracefully. +// The function is only executed if the process is gracefully +// shut down while this context is active. +// +// EXPERIMENTAL API: subject to change or removal. +func (ctx *Context) OnExit(f func(context.Context)) { + ctx.exitFuncs = append(ctx.exitFuncs, f) +} + // LoadModule loads the Caddy module(s) from the specified field of the parent struct // pointer and returns the loaded module(s). The struct pointer and its field name as // a string are necessary so that reflection can be used to read the struct tag on the From 8f8204708ac5f1dfdd0ffa7bcad1974ec54e18e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 02:38:57 +0300 Subject: [PATCH 3/3] ci: bump golangci/golangci-lint-action from 3 to 4 (#6141) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3 to 4. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v3...v4) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a538546ccf23..918734751854 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -47,7 +47,7 @@ jobs: check-latest: true - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v4 with: version: v1.55