pkg/skel: plugins now respond to VERSION command
To support CNI spec versioning, plugins must be able to report version information to container runtimes.
This commit is contained in:
parent
eda79f7645
commit
30c99d17cc
@ -24,6 +24,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
)
|
||||
|
||||
// CmdArgs captures all the arguments passed in to the plugin
|
||||
@ -40,7 +41,9 @@ type CmdArgs struct {
|
||||
type dispatcher struct {
|
||||
Getenv func(string) string
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
Versioner version.PluginVersioner
|
||||
}
|
||||
|
||||
type reqForCmdEntry map[string]bool
|
||||
@ -154,6 +157,9 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error) *types.Er
|
||||
case "DEL":
|
||||
err = cmdDel(cmdArgs)
|
||||
|
||||
case "VERSION":
|
||||
err = t.Versioner.Encode(t.Stdout)
|
||||
|
||||
default:
|
||||
return createTypedError("unknown CNI_COMMAND: %v", cmd)
|
||||
}
|
||||
@ -174,7 +180,9 @@ func PluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error) {
|
||||
caller := dispatcher{
|
||||
Getenv: os.Getenv,
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
Versioner: version.DefaultPluginVersioner,
|
||||
}
|
||||
|
||||
err := caller.pluginMain(cmdAdd, cmdDel)
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/testutils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
@ -48,7 +49,7 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
var (
|
||||
environment map[string]string
|
||||
stdin io.Reader
|
||||
stderr *bytes.Buffer
|
||||
stdout, stderr *bytes.Buffer
|
||||
cmdAdd, cmdDel *fakeCmd
|
||||
dispatch *dispatcher
|
||||
expectedCmdArgs *CmdArgs
|
||||
@ -64,11 +65,15 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
"CNI_PATH": "/some/cni/path",
|
||||
}
|
||||
stdin = strings.NewReader(`{ "some": "config" }`)
|
||||
stdout = &bytes.Buffer{}
|
||||
stderr = &bytes.Buffer{}
|
||||
versioner := &version.BasicVersioner{CNIVersion: "9.8.7"}
|
||||
dispatch = &dispatcher{
|
||||
Getenv: func(key string) string { return environment[key] },
|
||||
Stdin: stdin,
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
Versioner: versioner,
|
||||
}
|
||||
cmdAdd = &fakeCmd{}
|
||||
cmdDel = &fakeCmd{}
|
||||
@ -171,6 +176,36 @@ var _ = Describe("dispatching to the correct callback", func() {
|
||||
)
|
||||
})
|
||||
|
||||
Context("when the CNI_COMMAND is VERSION", func() {
|
||||
BeforeEach(func() {
|
||||
environment["CNI_COMMAND"] = "VERSION"
|
||||
})
|
||||
|
||||
It("prints the version to stdout", func() {
|
||||
err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(stdout).To(MatchJSON(`{ "cniVersion": "9.8.7" }`))
|
||||
})
|
||||
|
||||
It("does not call cmdAdd or cmdDel", func() {
|
||||
err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(cmdAdd.CallCount).To(Equal(0))
|
||||
Expect(cmdDel.CallCount).To(Equal(0))
|
||||
})
|
||||
|
||||
DescribeTable("VERSION does not need the usual env vars", envVarChecker,
|
||||
Entry("command", "CNI_COMMAND", true),
|
||||
Entry("container id", "CNI_CONTAINER_ID", false),
|
||||
Entry("net ns", "CNI_NETNS", false),
|
||||
Entry("if name", "CNI_IFNAME", false),
|
||||
Entry("args", "CNI_ARGS", false),
|
||||
Entry("path", "CNI_PATH", false),
|
||||
)
|
||||
})
|
||||
|
||||
Context("when the CNI_COMMAND is unrecognized", func() {
|
||||
BeforeEach(func() {
|
||||
environment["CNI_COMMAND"] = "NOPE"
|
||||
|
42
version/version.go
Normal file
42
version/version.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2016 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// A PluginVersioner can encode information about its version
|
||||
type PluginVersioner interface {
|
||||
Encode(io.Writer) error
|
||||
}
|
||||
|
||||
// BasicVersioner is a PluginVersioner which reports a single cniVersion string
|
||||
type BasicVersioner struct {
|
||||
CNIVersion string `json:"cniVersion"`
|
||||
}
|
||||
|
||||
func (p *BasicVersioner) Encode(w io.Writer) error {
|
||||
return json.NewEncoder(w).Encode(p)
|
||||
}
|
||||
|
||||
// Current reports the version of the CNI spec implemented by this library
|
||||
func Current() string {
|
||||
return "0.2.0"
|
||||
}
|
||||
|
||||
// DefaultPluginVersioner reports the Current library spec version as the cniVersion
|
||||
var DefaultPluginVersioner = &BasicVersioner{CNIVersion: Current()}
|
Loading…
x
Reference in New Issue
Block a user