docs: CNI versioning for 0.3.0 upgrade
This commit is contained in:
parent
1bc8141105
commit
328ea56e75
101
Documentation/spec-upgrades.md
Normal file
101
Documentation/spec-upgrades.md
Normal file
@ -0,0 +1,101 @@
|
||||
# CNI Plugin Versions, Compatibility, and Writing Plugins
|
||||
|
||||
## Specification Changes between CNI Specification Versions 0.2.0 and
|
||||
0.3.0
|
||||
|
||||
Plugins which conform to the CNI 0.3.0 specification may elect to
|
||||
return more expressive IPAM JSON that is not compatible with earlier
|
||||
specification versions. This requires updates to plugins that wish to
|
||||
conform to the 0.3.0 specification. It **does not** require updates to
|
||||
plugins that wish to only implement the 0.2.0 and earlier
|
||||
specifications.
|
||||
|
||||
## Multi-version Compatible Plugins
|
||||
|
||||
Plugins can also choose to support multiple CNI versions. The plugin is
|
||||
expected to return IPAM output conforming to the CNI specification
|
||||
version passed in the plugin's configuration on stdin in the
|
||||
`cniVersion` key. If that key is not present, then CNI specification
|
||||
version 0.2.0 should be assumed and 0.2.0 conforming JSON returned.
|
||||
Plugins should return all CNI specification versions they are
|
||||
compatible with when given the `VERSION` command, so runtimes can
|
||||
determine each plugins capabilities.
|
||||
|
||||
For example, if the plugin advertises only CNI specification version
|
||||
0.2.0 support and receives a `cniVersion` key of "0.3.0" the plugin
|
||||
must return an error. If the plugin advertises CNI specification
|
||||
support for 0.2.0 and 0.3.0, and receives `cniVersion` key of "0.2.0",
|
||||
the plugin must return IPAM JSON conforming to the CNI specification
|
||||
version 0.2.0.
|
||||
|
||||
## libcni API and Go Types Changes in 0.3.0
|
||||
|
||||
With the 0.5.0 CNI reference plugins and libcni release a number of
|
||||
important changes were made that affect both runtimes and plugin
|
||||
authors. These changes make it easier to enhance the libcni and plugin
|
||||
interfaces going forward. The largest changes are to the `types`
|
||||
package, which now contains multiple versions of libcni types. The
|
||||
`current` package contains the latest types, while types compatible
|
||||
with previous libcni releases will be placed into versioned packages
|
||||
like `types020` (representing the libcni types that conform to the CNI
|
||||
specification version 0.2.0).
|
||||
|
||||
The `Result` type is now an interface instead of a plain struct. The
|
||||
interface has new functions to convert the Result structure between
|
||||
different versions of the libcni types. Plugins and consumers of libcni
|
||||
should generally be written to use the Go types of the latest libcni
|
||||
release, and convert between the latest libcni types and the CNI
|
||||
specification type they are passed in the `cniVersion` key of plugin
|
||||
configuration.
|
||||
|
||||
### Plugins
|
||||
|
||||
For example, say your plugins supports both CNI specification version
|
||||
0.2.0 and 0.3.0. Your plugin receives configuration with a `cniVersion`
|
||||
key of "0.2.0". This means your plugin should return an IPAM structure
|
||||
conforming to the CNI specification version 0.2.0. The easiest way to
|
||||
code your plugin is to always use the most current libcni Result type
|
||||
(from the `current` package) and then immediately before exiting,
|
||||
convert that result to the requested CNI specification version result
|
||||
(eg, `types020`) and print it to stdout.
|
||||
|
||||
```
|
||||
import "github.com/containernetworking/cni/pkg/types"
|
||||
import "github.com/containernetworking/cni/pkg/types/current"
|
||||
|
||||
result := ¤t.Result{}
|
||||
<<< populate result here >>>
|
||||
return types.PrintResult(result, << CNI version from stdin net
|
||||
config>>)
|
||||
```
|
||||
|
||||
or if your plugin internally runs IPAM and needs to process the result:
|
||||
|
||||
```
|
||||
import "github.com/containernetworking/cni/pkg/types"
|
||||
import "github.com/containernetworking/cni/pkg/types/current"
|
||||
|
||||
ipamResult, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
|
||||
result, err := current.NewResultFromResult(ipamResult)
|
||||
<<< manipulate result here >>>
|
||||
return types.PrintResult(result, << CNI version from stdin net
|
||||
config>>)
|
||||
```
|
||||
|
||||
### Runtimes
|
||||
|
||||
Since libcni functions like AddNetwork() now return a Result interface
|
||||
rather than a plain structure, only a single additional step is
|
||||
required to convert that object to a structure you can manipulate
|
||||
internally. Runtimes should code to the most current Go types provided
|
||||
by the libcni they vendor into their sources, and can convert from
|
||||
whatever IPAM result version the plugin provides to the most current
|
||||
version like so:
|
||||
|
||||
```
|
||||
resultInterface, err := cninet.AddNetwork(netconf, rt)
|
||||
<<< resultInterface could wrap an object of any CNI specification
|
||||
version >>>
|
||||
realResult := current.NewResultFromResult(resultInterface)
|
||||
<<< realResult is a struct, not an interface >>>
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user