config: handle SIGHUP (#5459)

This commit is contained in:
Caleb Doxsey 2025-01-31 18:31:47 -07:00 committed by GitHub
parent dc9a6bdb81
commit 2754d20a2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 1 deletions

View file

@ -5,7 +5,9 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"os/signal"
"sync" "sync"
"syscall"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -145,6 +147,16 @@ func NewFileOrEnvironmentSource(
ch := src.watcher.Bind() ch := src.watcher.Bind()
go func() { go func() {
for range ch { for range ch {
log.Ctx(ctx).Info().Msg("config: file updated, reconfiguring...")
src.check(ctx)
}
}()
sch := make(chan os.Signal, 1)
signal.Notify(sch, syscall.SIGHUP)
go func() {
for range sch {
log.Ctx(ctx).Info().Msg("config: received SIGHUP, reloading config")
src.check(ctx) src.check(ctx)
} }
}() }()
@ -156,7 +168,6 @@ func (src *FileOrEnvironmentSource) check(ctx context.Context) {
ctx = log.WithContext(ctx, func(c zerolog.Context) zerolog.Context { ctx = log.WithContext(ctx, func(c zerolog.Context) zerolog.Context {
return c.Str("config_change_id", uuid.New().String()) return c.Str("config_change_id", uuid.New().String())
}) })
log.Ctx(ctx).Info().Msg("config: file updated, reconfiguring...")
src.mu.Lock() src.mu.Lock()
cfg := src.config cfg := src.config
options, err := newOptionsFromConfig(src.configFile) options, err := newOptionsFromConfig(src.configFile)

View file

@ -5,14 +5,23 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"syscall"
"testing" "testing"
"time" "time"
"github.com/rs/zerolog"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/signal"
"github.com/pomerium/pomerium/internal/testutil"
) )
func TestFileWatcherSource(t *testing.T) { func TestFileWatcherSource(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir() tmpdir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600) err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600)
@ -104,6 +113,8 @@ func TestFileWatcherSource(t *testing.T) {
} }
func TestFileOrEnvironmentSource(t *testing.T) { func TestFileOrEnvironmentSource(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir() tmpdir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600) err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600)
@ -201,4 +212,33 @@ runtime_flags:
t.Run("Hot Reload Enabled", newTest(true)) t.Run("Hot Reload Enabled", newTest(true))
t.Run("Hot Reload Disabled", newTest(false)) t.Run("Hot Reload Disabled", newTest(false))
t.Run("SIGHUP", func(t *testing.T) {
t.Parallel()
ready := signal.New()
readyCh := ready.Bind()
ctx := testutil.GetContext(t, time.Minute)
ctx = log.Ctx(ctx).Hook(zerolog.HookFunc(func(_ *zerolog.Event, _ zerolog.Level, message string) {
if strings.Contains(message, "received SIGHUP") {
ready.Broadcast(ctx)
}
})).WithContext(ctx)
tmp := t.TempDir()
cfgFP := filepath.Join(tmp, "config.json")
require.NoError(t, os.WriteFile(cfgFP, []byte(`{}`), 0o600))
_, err := NewFileOrEnvironmentSource(ctx, cfgFP, "")
assert.NoError(t, err)
require.NoError(t, syscall.Kill(syscall.Getpid(), syscall.SIGHUP))
select {
case <-ctx.Done():
t.Error("expected to receive SIGHUP log message")
case <-readyCh:
}
})
} }