mirror of
https://github.com/safing/portbase
synced 2025-09-01 10:09:50 +00:00
Fix handling of unmapped configuration options
This commit is contained in:
parent
900a654a4d
commit
34453d6989
2 changed files with 39 additions and 1 deletions
|
@ -11,6 +11,12 @@ import (
|
|||
var (
|
||||
optionsLock sync.RWMutex
|
||||
options = make(map[string]*Option)
|
||||
|
||||
// unmappedValues holds a list of configuration values that have been
|
||||
// read from the persistence layer but no option has been defined yet.
|
||||
// This is mainly to support the plugin system of the Portmaster.
|
||||
unmappedValuesLock sync.Mutex
|
||||
unmappedValues map[string]interface{}
|
||||
)
|
||||
|
||||
// ForEachOption calls fn for each defined option. If fn returns
|
||||
|
@ -98,9 +104,29 @@ func Register(option *Option) error {
|
|||
return fmt.Errorf("config: invalid default value: %w", vErr)
|
||||
}
|
||||
|
||||
if err := loadUnmappedValue(option); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
optionsLock.Lock()
|
||||
defer optionsLock.Unlock()
|
||||
options[option.Key] = option
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadUnmappedValue(option *Option) error {
|
||||
unmappedValuesLock.Lock()
|
||||
defer unmappedValuesLock.Unlock()
|
||||
if value, ok := unmappedValues[option.Key]; ok {
|
||||
delete(unmappedValues, option.Key)
|
||||
|
||||
var vErr *ValidationError
|
||||
option.activeValue, vErr = validateValue(option, value)
|
||||
if vErr != nil {
|
||||
return fmt.Errorf("config: invalid value: %w", vErr)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ func signalChanges() {
|
|||
func replaceConfig(newValues map[string]interface{}) []*ValidationError {
|
||||
var validationErrors []*ValidationError
|
||||
|
||||
valuesCopy := make(map[string]interface{}, len(newValues))
|
||||
for key, value := range newValues {
|
||||
valuesCopy[key] = value
|
||||
}
|
||||
|
||||
// RLock the options because we are not adding or removing
|
||||
// options from the registration but rather only update the
|
||||
// options value which is guarded by the option's lock itself
|
||||
|
@ -48,7 +53,9 @@ func replaceConfig(newValues map[string]interface{}) []*ValidationError {
|
|||
defer optionsLock.RUnlock()
|
||||
|
||||
for key, option := range options {
|
||||
newValue, ok := newValues[key]
|
||||
newValue, ok := valuesCopy[key]
|
||||
|
||||
delete(valuesCopy, key)
|
||||
|
||||
option.Lock()
|
||||
option.activeValue = nil
|
||||
|
@ -66,6 +73,11 @@ func replaceConfig(newValues map[string]interface{}) []*ValidationError {
|
|||
option.Unlock()
|
||||
}
|
||||
|
||||
unmappedValuesLock.Lock()
|
||||
defer unmappedValuesLock.Unlock()
|
||||
|
||||
unmappedValues = valuesCopy
|
||||
|
||||
signalChanges()
|
||||
|
||||
return validationErrors
|
||||
|
|
Loading…
Add table
Reference in a new issue