// GetVersionInfo returns the version information available about the plugin. // For recent-enough plugins, it uses the information returned by the VERSION // command. For older plugins which do not recognize that command, it reports // version 0.1.0 func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, error) { args := &Args{ Command: "VERSION", // set fake values required by plugins built against an older version of skel NetNS: "dummy", IfName: "dummy", Path: "dummy", } stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, nil, args.AsEnv()) if err != nil { if err.Error() == "unknown CNI_COMMAND: VERSION" { return version.PluginSupports("0.1.0"), nil } return nil, err } return e.VersionDecoder.Decode(stdoutBytes) }
versionInfo version.PluginInfo ) BeforeEach(func() { environment = map[string]string{ "CNI_COMMAND": "ADD", "CNI_CONTAINERID": "some-container-id", "CNI_NETNS": "/some/netns/path", "CNI_IFNAME": "eth0", "CNI_ARGS": "some;extra;args", "CNI_PATH": "/some/cni/path", } stdin = strings.NewReader(`{ "some": "config" }`) stdout = &bytes.Buffer{} stderr = &bytes.Buffer{} versionInfo = version.PluginSupports("9.8.7") dispatch = &dispatcher{ Getenv: func(key string) string { return environment[key] }, Stdin: stdin, Stdout: stdout, Stderr: stderr, } cmdAdd = &fakeCmd{} cmdDel = &fakeCmd{} expectedCmdArgs = &CmdArgs{ ContainerID: "some-container-id", Netns: "/some/netns/path", IfName: "eth0", Args: "some;extra;args", Path: "/some/cni/path", StdinData: []byte(`{ "some": "config" }`),
var ( pluginExec *invoke.PluginExec rawExec *fakes.RawExec versionDecoder *fakes.VersionDecoder pluginPath string netconf []byte cniargs *fakes.CNIArgs ) BeforeEach(func() { rawExec = &fakes.RawExec{} rawExec.ExecPluginCall.Returns.ResultBytes = []byte(`{ "ip4": { "ip": "1.2.3.4/24" } }`) versionDecoder = &fakes.VersionDecoder{} versionDecoder.DecodeCall.Returns.PluginInfo = version.PluginSupports("0.42.0") pluginExec = &invoke.PluginExec{ RawExec: rawExec, VersionDecoder: versionDecoder, } pluginPath = "/some/plugin/path" netconf = []byte(`{ "some": "stdin" }`) cniargs = &fakes.CNIArgs{} cniargs.AsEnvCall.Returns.Env = []string{"SOME=ENV"} }) Describe("returning a result", func() { It("unmarshals the result bytes into the Result type", func() { result, err := pluginExec.WithResult(pluginPath, netconf, cniargs) Expect(err).NotTo(HaveOccurred())
AfterEach(func() { Expect(os.RemoveAll(pluginDir)).To(Succeed()) }) DescribeTable("correctly reporting plugin versions", func(gitRef string, pluginSource string, expectedVersions version.PluginInfo) { Expect(testhelpers.BuildAt([]byte(pluginSource), gitRef, pluginPath)).To(Succeed()) versionInfo, err := invoke.GetVersionInfo(pluginPath) Expect(err).NotTo(HaveOccurred()) Expect(versionInfo.SupportedVersions()).To(ConsistOf(expectedVersions.SupportedVersions())) }, Entry("historical: before VERSION was introduced", git_ref_v010, plugin_source_no_custom_versions, version.PluginSupports("0.1.0"), ), Entry("historical: when VERSION was introduced but plugins couldn't customize it", git_ref_v020_no_custom_versions, plugin_source_no_custom_versions, version.PluginSupports("0.1.0", "0.2.0"), ), Entry("historical: when plugins started reporting their own version list", git_ref_v020_custom_versions, plugin_source_v020_custom_versions, version.PluginSupports("0.2.0", "0.999.0"), ), // this entry tracks the current behavior. Before you change it, ensure // that its previous behavior is captured in the most recent "historical" entry Entry("current",