-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(upgrade): ensure query config written by influxd upgrade
is valid
#21321
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
a6b64e6
test: refactor upgrade test to cover the config upgrade
danxmoran 21c176f
fix: ensure upgraded query config is valid
danxmoran 7b6ad25
chore: fix formatting
danxmoran b7d0390
chore: update CHANGELOG
danxmoran 3665860
Merge branch 'master' into dm-influxd-upgrade-invalid-config-21315
danxmoran File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,8 +16,9 @@ import ( | |
"golang.org/x/text/transform" | ||
) | ||
|
||
// configMapRules is a map of transformation rules | ||
var configMapRules = map[string]string{ | ||
// passthroughConfigRules maps v1 config key-names to corresponding v2 config key-names. | ||
// The values of these configs will not be modified during the upgrade process. | ||
var passthroughConfigRules = map[string]string{ | ||
"reporting-disabled": "reporting-disabled", | ||
"data.dir": "engine-path", | ||
"data.wal-fsync-delay": "storage-wal-fsync-delay", | ||
|
@@ -43,31 +44,6 @@ var configMapRules = map[string]string{ | |
"http.bind-address": "http-bind-address", | ||
"http.https-certificate": "tls-cert", | ||
"http.https-private-key": "tls-key", | ||
"http.pprof-enabled": "pprof-disabled", | ||
} | ||
|
||
// configValueTransforms is a map from 2.x config keys to transformation functions | ||
// that should run on the 1.x values before they're written into the 2.x config. | ||
var configValueTransforms = map[string]func(interface{}) interface{}{ | ||
// Transform config values of 0 into 10 (the new default). | ||
// query-concurrency used to accept 0 as a representation of infinity, | ||
// but the 2.x controller now forces a positive value to be chosen | ||
// for the parameter. | ||
"query-concurrency": func(v interface{}) interface{} { | ||
ret := v | ||
if i, ok := v.(int64); ok && i == 0 { | ||
ret = 10 | ||
} | ||
return ret | ||
}, | ||
// Flip the boolean (1.x tracked 'enabled', 2.x tracks 'disabled'). | ||
"pprof-disabled": func(v interface{}) interface{} { | ||
ret := v | ||
if b, ok := v.(bool); ok { | ||
ret = !b | ||
} | ||
return ret | ||
}, | ||
} | ||
|
||
func loadV1Config(configFile string) (*configV1, *map[string]interface{}, error) { | ||
|
@@ -120,9 +96,8 @@ func load(path string) ([]byte, error) { | |
func upgradeConfig(v1Config map[string]interface{}, targetOptions optionsV2, log *zap.Logger) error { | ||
// create and initialize helper | ||
cu := &configUpgrader{ | ||
rules: configMapRules, | ||
valueTransforms: configValueTransforms, | ||
log: log, | ||
rules: passthroughConfigRules, | ||
log: log, | ||
} | ||
|
||
// rewrite config options from V1 to V2 paths | ||
|
@@ -137,9 +112,8 @@ func upgradeConfig(v1Config map[string]interface{}, targetOptions optionsV2, log | |
|
||
// configUpgrader is a helper used by `upgrade-config` command. | ||
type configUpgrader struct { | ||
rules map[string]string | ||
valueTransforms map[string]func(interface{}) interface{} | ||
log *zap.Logger | ||
rules map[string]string | ||
log *zap.Logger | ||
} | ||
|
||
func (cu *configUpgrader) updateV2Config(config map[string]interface{}, targetOptions optionsV2) { | ||
|
@@ -168,36 +142,70 @@ func (cu *configUpgrader) save(config map[string]interface{}, path string) error | |
|
||
// Credits: @rogpeppe (Roger Peppe) | ||
|
||
func (cu *configUpgrader) transform(x map[string]interface{}) map[string]interface{} { | ||
func (cu *configUpgrader) transform(v1Config map[string]interface{}) map[string]interface{} { | ||
res := make(map[string]interface{}) | ||
for old, new := range cu.rules { | ||
val, ok := cu.lookup(x, old) | ||
if ok { | ||
if transform, ok := cu.valueTransforms[new]; ok { | ||
val = transform(val) | ||
} | ||
if val, ok := cu.lookup(v1Config, old); ok { | ||
res[new] = val | ||
} | ||
} | ||
|
||
// Special case: flip the value for pprof. | ||
if val, ok := cu.lookup(v1Config, "http.pprof-enabled"); ok { | ||
if b, ok := val.(bool); ok { | ||
res["pprof-disabled"] = !b | ||
} | ||
} | ||
|
||
// Special case: ensure query settings are valid. | ||
fixQueryLimits(res) | ||
|
||
return res | ||
} | ||
|
||
func (cu *configUpgrader) lookup(x map[string]interface{}, path string) (interface{}, bool) { | ||
// fixQueryLimits ensures that all query-related config settings are compatible | ||
// with the upgraded value of the 'query-concurrency' setting. | ||
func fixQueryLimits(v2Config map[string]interface{}) { | ||
concurrencyVal, ok := v2Config["query-concurrency"] | ||
if !ok { | ||
return | ||
} | ||
var concurrency int64 | ||
switch c := concurrencyVal.(type) { | ||
case int: | ||
concurrency = int64(c) | ||
case int32: | ||
concurrency = int64(c) | ||
case int64: | ||
concurrency = c | ||
default: | ||
concurrency = 0 | ||
} | ||
if concurrency == 0 { | ||
// The upgrade process doesn't generate a value for query-queue-size, so if | ||
// query-concurrency is 0 / unset then it's safe to leave query-queue-size unset. | ||
return | ||
} | ||
|
||
// When query-concurrency is > 0, query-queue-size must also be > 0. | ||
v2Config["query-queue-size"] = concurrency | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a risk here that:
I'm assuming the risk is low now that we support 0 for unlimited, so most people who would be writing huge concurrency values can now write 0 instead. |
||
} | ||
|
||
func (cu *configUpgrader) lookup(v1Config map[string]interface{}, path string) (interface{}, bool) { | ||
for { | ||
elem := path | ||
rest := "" | ||
if i := strings.Index(path, "."); i != -1 { | ||
elem, rest = path[0:i], path[i+1:] | ||
} | ||
val, ok := x[elem] | ||
val, ok := v1Config[elem] | ||
if rest == "" { | ||
return val, ok | ||
} | ||
child, ok := val.(map[string]interface{}) | ||
if !ok { | ||
return nil, false | ||
} | ||
path, x = rest, child | ||
path, v1Config = rest, child | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these cases are paranoia on my part; I'm not sure when the config-loader would pick each type of int.