Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Commit 328c725

Browse files
pracuccigouthamve
authored andcommitted
Fail to startup Cortex if provided runtime config is invalid (cortexproject#3707)
Signed-off-by: Marco Pracucci <marco@pracucci.com>
1 parent 4559022 commit 328c725

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* [ENHANCEMENT] Disabled in-memory shuffle-sharding subring cache in the store-gateway, ruler and compactor. This should reduce the memory utilisation in these services when shuffle-sharding is enabled, without introducing a significantly increase CPU utilisation. #3601
3737
* [ENHANCEMENT] Shuffle sharding: optimised subring generation used by shuffle sharding. #3601
3838
* [ENHANCEMENT] New /runtime_config endpoint that returns the defined runtime configuration in YAML format. The returned configuration includes overrides. #3639
39+
* [ENHANCEMENT] Fail to startup Cortex if provided runtime config is invalid. #3707
3940
* [BUGFIX] Allow `-querier.max-query-lookback` use `y|w|d` suffix like deprecated `-store.max-look-back-period`. #3598
4041
* [BUGFIX] Memberlist: Entry in the ring should now not appear again after using "Forget" feature (unless it's still heartbeating). #3603
4142
* [BUGFIX] Ingester: do not close idle TSDBs while blocks shipping is in progress. #3630

pkg/util/runtimeconfig/manager.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"context"
66
"crypto/sha256"
7-
"errors"
87
"flag"
98
"fmt"
109
"io"
@@ -13,6 +12,7 @@ import (
1312
"time"
1413

1514
"github.com/go-kit/kit/log/level"
15+
"github.com/pkg/errors"
1616
"github.com/prometheus/client_golang/prometheus"
1717
"github.com/prometheus/client_golang/prometheus/promauto"
1818

@@ -74,18 +74,16 @@ func NewRuntimeConfigManager(cfg ManagerConfig, registerer prometheus.Registerer
7474
}, []string{"sha256"}),
7575
}
7676

77-
mgr.Service = services.NewBasicService(mgr.start, mgr.loop, mgr.stop)
77+
mgr.Service = services.NewBasicService(mgr.starting, mgr.loop, mgr.stopping)
7878
return &mgr, nil
7979
}
8080

81-
func (om *Manager) start(_ context.Context) error {
82-
if om.cfg.LoadPath != "" {
83-
if err := om.loadConfig(); err != nil {
84-
// Log but don't stop on error - we don't want to halt all ingesters because of a typo
85-
level.Error(util.Logger).Log("msg", "failed to load config", "err", err)
86-
}
81+
func (om *Manager) starting(_ context.Context) error {
82+
if om.cfg.LoadPath == "" {
83+
return nil
8784
}
88-
return nil
85+
86+
return errors.Wrap(om.loadConfig(), "failed to load runtime config")
8987
}
9088

9189
// CreateListenerChannel creates new channel that can be used to receive new config values.
@@ -190,7 +188,7 @@ func (om *Manager) callListeners(newValue interface{}) {
190188
}
191189

192190
// Stop stops the Manager
193-
func (om *Manager) stop(_ error) error {
191+
func (om *Manager) stopping(_ error) error {
194192
om.listenersMtx.Lock()
195193
defer om.listenersMtx.Unlock()
196194

pkg/util/runtimeconfig/manager_test.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func TestNewOverridesManager(t *testing.T) {
111111
require.NotNil(t, overridesManager.GetConfig())
112112
}
113113

114-
func TestOverridesManager_ListenerWithDefaultLimits(t *testing.T) {
114+
func TestManager_ListenerWithDefaultLimits(t *testing.T) {
115115
tempFile, err := ioutil.TempFile("", "test-validation")
116116
require.NoError(t, err)
117117
require.NoError(t, tempFile.Close())
@@ -195,7 +195,7 @@ func TestOverridesManager_ListenerWithDefaultLimits(t *testing.T) {
195195
require.NotNil(t, overridesManager.GetConfig())
196196
}
197197

198-
func TestOverridesManager_ListenerChannel(t *testing.T) {
198+
func TestManager_ListenerChannel(t *testing.T) {
199199
config, overridesManagerConfig := newTestOverridesManagerConfig(t, 555)
200200

201201
overridesManager, err := NewRuntimeConfigManager(overridesManagerConfig, nil)
@@ -235,7 +235,7 @@ func TestOverridesManager_ListenerChannel(t *testing.T) {
235235
}
236236
}
237237

238-
func TestOverridesManager_StopClosesListenerChannels(t *testing.T) {
238+
func TestManager_StopClosesListenerChannels(t *testing.T) {
239239
_, overridesManagerConfig := newTestOverridesManagerConfig(t, 555)
240240

241241
overridesManager, err := NewRuntimeConfigManager(overridesManagerConfig, nil)
@@ -254,3 +254,27 @@ func TestOverridesManager_StopClosesListenerChannels(t *testing.T) {
254254
t.Fatal("channel not closed")
255255
}
256256
}
257+
258+
func TestManager_ShouldFastFailOnInvalidConfigAtStartup(t *testing.T) {
259+
// Create an invalid runtime config file.
260+
tempFile, err := ioutil.TempFile("", "invalid-config")
261+
require.NoError(t, err)
262+
t.Cleanup(func() {
263+
require.NoError(t, os.Remove(tempFile.Name()))
264+
})
265+
266+
_, err = tempFile.Write([]byte("!invalid!"))
267+
require.NoError(t, err)
268+
require.NoError(t, tempFile.Close())
269+
270+
// Create the config manager and start it.
271+
cfg := ManagerConfig{
272+
ReloadPeriod: time.Second,
273+
LoadPath: tempFile.Name(),
274+
Loader: testLoadOverrides,
275+
}
276+
277+
m, err := NewRuntimeConfigManager(cfg, nil)
278+
require.NoError(t, err)
279+
require.Error(t, services.StartAndAwaitRunning(context.Background(), m))
280+
}

0 commit comments

Comments
 (0)