Go-based plugins can use the cni library to handle multiple spec versions easily. In recent versions, types.Result is an interface, and concrete implementations reside in subpackages like types/100, types/040, and types/020.
Implementation Pattern:
- Use the latest spec version structs (e.g.,
types/100) for internal plugin logic. - Use
types.PrintResult(result, cniVersion) to convert and print the result to stdout in the format requested by the cniVersion in the configuration. - Advertise supported versions via the third argument to
skel.PluginMain().
import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
)
func cmdAdd(args *skel.CmdArgs) error {
// determine spec version to use
var netConf struct {
types.NetConf
// other plugin-specific configuration goes here
}
err := json.Unmarshal(args.StdinData, &netConf)
cniVersion := netConf.CNIVersion
// plugin does its work...
// set up interfaces
// assign addresses, etc
// construct the result
result := ¤t.Result{
Interfaces: []*current.Interface{ ... },
IPs: []*current.IPs{ ... },
...
}
// print result to stdout, in the format defined by the requested cniVersion
return types.PrintResult(result, cniVersion)
}
func main() {
skel.PluginMain(cmdAdd, cmdDel, version.All)
}