api,libcni: add network config list-based plugin chaining

Using a new ".configlist" file format that allows specifying
a list of CNI network configurations to run, add new libcni
helper functions to call each plugin in the list, injecting
the overall name, CNI version, and previous plugin's Result
structure into the configuration of the next plugin.
This commit is contained in:
Dan Williams
2016-12-16 18:56:39 -06:00
parent 7e16c86a52
commit 0c2a034f01
7 changed files with 696 additions and 153 deletions

View File

@ -34,7 +34,17 @@ type NetworkConfig struct {
Bytes []byte
}
type NetworkConfigList struct {
Name string
CNIVersion string
Plugins []*NetworkConfig
Bytes []byte
}
type CNI interface {
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (*types.Result, error)
DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error
AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error)
DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}
@ -46,6 +56,76 @@ type CNIConfig struct {
// CNIConfig implements the CNI interface
var _ CNI = &CNIConfig{}
func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult *types.Result) (*NetworkConfig, error) {
var err error
// Ensure every config uses the same name and version
orig, err = InjectConf(orig, "name", list.Name)
if err != nil {
return nil, err
}
orig, err = InjectConf(orig, "cniVersion", list.CNIVersion)
if err != nil {
return nil, err
}
// Add previous plugin result
if prevResult != nil {
orig, err = InjectConf(orig, "prevResult", prevResult)
if err != nil {
return nil, err
}
}
return orig, nil
}
// AddNetworkList executes a sequence of plugins with the ADD command
func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (*types.Result, error) {
var prevResult *types.Result
for _, net := range list.Plugins {
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
if err != nil {
return nil, err
}
newConf, err := buildOneConfig(list, net, prevResult)
if err != nil {
return nil, err
}
prevResult, err = invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args("ADD", rt))
if err != nil {
return nil, err
}
}
return prevResult, nil
}
// DelNetworkList executes a sequence of plugins with the DEL command
func (c *CNIConfig) DelNetworkList(list *NetworkConfigList, rt *RuntimeConf) error {
for i := len(list.Plugins) - 1; i >= 0; i-- {
net := list.Plugins[i]
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
if err != nil {
return err
}
newConf, err := buildOneConfig(list, net, nil)
if err != nil {
return err
}
if err := invoke.ExecPluginWithoutResult(pluginPath, newConf.Bytes, c.args("DEL", rt)); err != nil {
return err
}
}
return nil
}
// AddNetwork executes the plugin with the ADD command
func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (*types.Result, error) {
pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)