aec99d6f80
Signed-off-by: Dan Williams <dcbw@redhat.com>
95 lines
3 KiB
Go
95 lines
3 KiB
Go
// Copyright 2015 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 invoke
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/containernetworking/cni/pkg/types"
|
|
"github.com/containernetworking/cni/pkg/version"
|
|
)
|
|
|
|
func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
|
return defaultPluginExec.WithResult(pluginPath, netconf, args)
|
|
}
|
|
|
|
func ExecPluginWithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
|
return defaultPluginExec.WithoutResult(pluginPath, netconf, args)
|
|
}
|
|
|
|
func GetVersionInfo(pluginPath string) (version.PluginInfo, error) {
|
|
return defaultPluginExec.GetVersionInfo(pluginPath)
|
|
}
|
|
|
|
var defaultPluginExec = &PluginExec{
|
|
RawExec: &RawExec{Stderr: os.Stderr},
|
|
VersionDecoder: &version.PluginDecoder{},
|
|
}
|
|
|
|
type PluginExec struct {
|
|
RawExec interface {
|
|
ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error)
|
|
}
|
|
VersionDecoder interface {
|
|
Decode(jsonBytes []byte) (version.PluginInfo, error)
|
|
}
|
|
}
|
|
|
|
func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) {
|
|
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Plugin must return result in same version as specified in netconf
|
|
versionDecoder := &version.ConfigDecoder{}
|
|
confVersion, err := versionDecoder.Decode(netconf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return version.NewResult(confVersion, stdoutBytes)
|
|
}
|
|
|
|
func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIArgs) error {
|
|
_, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv())
|
|
return err
|
|
}
|
|
|
|
// 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",
|
|
}
|
|
stdin := []byte(fmt.Sprintf(`{"cniVersion":%q}`, version.Current()))
|
|
stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, stdin, 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)
|
|
}
|