Skip to content

Commit

Permalink
option: Add dependency management
Browse files Browse the repository at this point in the history
Allows specifying a list of dependencies to each option which are
automatically enabled and disabled.

Fixes: #245

Signed-off-by:  <thomas@cilium.io>
  • Loading branch information
tgraf committed Mar 18, 2017
1 parent 7338f4d commit fbc8b5c
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
2 changes: 2 additions & 0 deletions pkg/endpoint/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ var (
OptionSpecConntrackAccounting = option.Option{
Define: "CONNTRACK_ACCOUNTING",
Description: "Enable per flow (conntrack) statistics",
Requires: []string{OptionConntrack},
}

OptionSpecConntrack = option.Option{
Expand All @@ -99,6 +100,7 @@ var (
OptionSpecNAT46 = option.Option{
Define: "ENABLE_NAT46",
Description: "Enable automatic NAT46 translation",
Requires: []string{OptionConntrack},
}

OptionSpecPolicy = option.Option{
Expand Down
51 changes: 49 additions & 2 deletions pkg/option/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ type Option struct {
Define string
Description string
Immutable bool
Requires []string
}

// Requires returns true if the option requires the specified option `name`
func (o Option) RequiresOption(name string) bool {
for _, o := range o.Requires {
if o == name {
return true
}
}

return false
}

type OptionLibrary map[string]*Option
Expand Down Expand Up @@ -234,6 +246,7 @@ func (o *BoolOptions) Dump() {
}
}

// Validate validates a given configuration map based on the option library
func (o *BoolOptions) Validate(n models.ConfigurationMap) error {
for k, v := range n {
if _, err := NormalizeBool(v); err != nil {
Expand All @@ -248,8 +261,42 @@ func (o *BoolOptions) Validate(n models.ConfigurationMap) error {
return nil
}

// ChangedFunc is called by `Apply()` for each option changed
type ChangedFunc func(key string, value bool, data interface{})

// Enable enables the option `name` with all its dependencies
func (o *BoolOptions) Enable(name string) {
if o.Library != nil {
if _, opt := o.Library.Lookup(name); opt != nil {
for _, dependency := range opt.Requires {
o.Enable(dependency)
}
}
}

o.Opts[name] = true
}

// Disable disables the option `name`. All options which depend on the option
// to be disabled will be disabled. Options which have previously been enabled
// as a dependency will not be automatically disabled.
func (o *BoolOptions) Disable(name string) {
o.Opts[name] = false

if o.Library != nil {
// Disable all options which have a dependency on the option
// that was just disabled
for key, opt := range *o.Library {
if opt.RequiresOption(name) && o.Opts[key] {
o.Disable(key)
}
}
}
}

// Apply takes a configuration map and applies the changes. For an option
// which is changed, the `ChangedFunc` function is called with the `data`
// argument passed in as well. Returns the number of options changed if any.
func (o *BoolOptions) Apply(n models.ConfigurationMap, changed ChangedFunc, data interface{}) int {
changes := 0

Expand All @@ -259,14 +306,14 @@ func (o *BoolOptions) Apply(n models.ConfigurationMap, changed ChangedFunc, data
if boolVal, _ := NormalizeBool(v); boolVal {
/* Only enable if not enabled already */
if !ok || !val {
o.Opts[k] = true
o.Enable(k)
changes++
changed(k, true, data)
}
} else {
/* Only disable if enabled already */
if ok && val {
o.Opts[k] = false
o.Disable(k)
changes++
changed(k, false, data)
}
Expand Down

0 comments on commit fbc8b5c

Please sign in to comment.