2
go.mod
2
go.mod
@ -7,7 +7,7 @@ require (
|
|||||||
github.com/Microsoft/hcsshim v0.8.6
|
github.com/Microsoft/hcsshim v0.8.6
|
||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
||||||
github.com/containernetworking/cni v0.7.1
|
github.com/containernetworking/cni v0.8.0
|
||||||
github.com/coreos/go-iptables v0.4.5
|
github.com/coreos/go-iptables v0.4.5
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
|
||||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
|
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
|
||||||
|
4
go.sum
4
go.sum
@ -6,8 +6,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae h1:AMzIhMUq
|
|||||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44 h1:y853v6rXx+zefEcjET3JuKAqvhj+FKflQijjeaSv2iA=
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44 h1:y853v6rXx+zefEcjET3JuKAqvhj+FKflQijjeaSv2iA=
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/containernetworking/cni v0.7.1 h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=
|
github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI=
|
||||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||||
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
|
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
|
||||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7 h1:u9SHYsPQNyt5tgDm3YN7+9dYrpK96E5wFilTFWIDZOM=
|
||||||
|
230
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
230
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/invoke"
|
"github.com/containernetworking/cni/pkg/invoke"
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
"github.com/containernetworking/cni/pkg/utils"
|
||||||
"github.com/containernetworking/cni/pkg/version"
|
"github.com/containernetworking/cni/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,6 +33,10 @@ var (
|
|||||||
CacheDir = "/var/lib/cni"
|
CacheDir = "/var/lib/cni"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CNICacheV1 = "cniCacheV1"
|
||||||
|
)
|
||||||
|
|
||||||
// A RuntimeConf holds the arguments to one invocation of a CNI plugin
|
// A RuntimeConf holds the arguments to one invocation of a CNI plugin
|
||||||
// excepting the network configuration, with the nested exception that
|
// excepting the network configuration, with the nested exception that
|
||||||
// the `runtimeConfig` from the network configuration is included
|
// the `runtimeConfig` from the network configuration is included
|
||||||
@ -48,7 +53,7 @@ type RuntimeConf struct {
|
|||||||
// to the plugin
|
// to the plugin
|
||||||
CapabilityArgs map[string]interface{}
|
CapabilityArgs map[string]interface{}
|
||||||
|
|
||||||
// A cache directory in which to library data. Defaults to CacheDir
|
// DEPRECATED. Will be removed in a future release.
|
||||||
CacheDir string
|
CacheDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,11 +75,13 @@ type CNI interface {
|
|||||||
CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
||||||
DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
DelNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
|
||||||
GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
GetNetworkListCachedResult(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||||
|
GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||||
|
|
||||||
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||||
CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
||||||
DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
|
||||||
GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||||
|
GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||||
|
|
||||||
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
|
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
|
||||||
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
|
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
|
||||||
@ -83,6 +90,7 @@ type CNI interface {
|
|||||||
type CNIConfig struct {
|
type CNIConfig struct {
|
||||||
Path []string
|
Path []string
|
||||||
exec invoke.Exec
|
exec invoke.Exec
|
||||||
|
cacheDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// CNIConfig implements the CNI interface
|
// CNIConfig implements the CNI interface
|
||||||
@ -92,8 +100,17 @@ var _ CNI = &CNIConfig{}
|
|||||||
// in the given paths and use the given exec interface to run those plugins,
|
// in the given paths and use the given exec interface to run those plugins,
|
||||||
// or if the exec interface is not given, will use a default exec handler.
|
// or if the exec interface is not given, will use a default exec handler.
|
||||||
func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig {
|
func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig {
|
||||||
|
return NewCNIConfigWithCacheDir(path, "", exec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCNIConfigWithCacheDir returns a new CNIConfig object that will search for plugins
|
||||||
|
// in the given paths use the given exec interface to run those plugins,
|
||||||
|
// or if the exec interface is not given, will use a default exec handler.
|
||||||
|
// The given cache directory will be used for temporary data storage when needed.
|
||||||
|
func NewCNIConfigWithCacheDir(path []string, cacheDir string, exec invoke.Exec) *CNIConfig {
|
||||||
return &CNIConfig{
|
return &CNIConfig{
|
||||||
Path: path,
|
Path: path,
|
||||||
|
cacheDir: cacheDir,
|
||||||
exec: exec,
|
exec: exec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,33 +182,122 @@ func (c *CNIConfig) ensureExec() invoke.Exec {
|
|||||||
return c.exec
|
return c.exec
|
||||||
}
|
}
|
||||||
|
|
||||||
func getResultCacheFilePath(netName string, rt *RuntimeConf) string {
|
type cachedInfo struct {
|
||||||
cacheDir := rt.CacheDir
|
Kind string `json:"kind"`
|
||||||
if cacheDir == "" {
|
ContainerID string `json:"containerId"`
|
||||||
cacheDir = CacheDir
|
Config []byte `json:"config"`
|
||||||
}
|
IfName string `json:"ifName"`
|
||||||
return filepath.Join(cacheDir, "results", fmt.Sprintf("%s-%s-%s", netName, rt.ContainerID, rt.IfName))
|
NetworkName string `json:"networkName"`
|
||||||
|
CniArgs [][2]string `json:"cniArgs,omitempty"`
|
||||||
|
CapabilityArgs map[string]interface{} `json:"capabilityArgs,omitempty"`
|
||||||
|
RawResult map[string]interface{} `json:"result,omitempty"`
|
||||||
|
Result types.Result `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCachedResult(result types.Result, netName string, rt *RuntimeConf) error {
|
// getCacheDir returns the cache directory in this order:
|
||||||
|
// 1) global cacheDir from CNIConfig object
|
||||||
|
// 2) deprecated cacheDir from RuntimeConf object
|
||||||
|
// 3) fall back to default cache directory
|
||||||
|
func (c *CNIConfig) getCacheDir(rt *RuntimeConf) string {
|
||||||
|
if c.cacheDir != "" {
|
||||||
|
return c.cacheDir
|
||||||
|
}
|
||||||
|
if rt.CacheDir != "" {
|
||||||
|
return rt.CacheDir
|
||||||
|
}
|
||||||
|
return CacheDir
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CNIConfig) getCacheFilePath(netName string, rt *RuntimeConf) (string, error) {
|
||||||
|
if netName == "" || rt.ContainerID == "" || rt.IfName == "" {
|
||||||
|
return "", fmt.Errorf("cache file path requires network name (%q), container ID (%q), and interface name (%q)", netName, rt.ContainerID, rt.IfName)
|
||||||
|
}
|
||||||
|
return filepath.Join(c.getCacheDir(rt), "results", fmt.Sprintf("%s-%s-%s", netName, rt.ContainerID, rt.IfName)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string, rt *RuntimeConf) error {
|
||||||
|
cached := cachedInfo{
|
||||||
|
Kind: CNICacheV1,
|
||||||
|
ContainerID: rt.ContainerID,
|
||||||
|
Config: config,
|
||||||
|
IfName: rt.IfName,
|
||||||
|
NetworkName: netName,
|
||||||
|
CniArgs: rt.Args,
|
||||||
|
CapabilityArgs: rt.CapabilityArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to get type.Result into cachedInfo as JSON map
|
||||||
|
// Marshal to []byte, then Unmarshal into cached.RawResult
|
||||||
data, err := json.Marshal(result)
|
data, err := json.Marshal(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fname := getResultCacheFilePath(netName, rt)
|
|
||||||
|
err = json.Unmarshal(data, &cached.RawResult)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newBytes, err := json.Marshal(&cached)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fname, err := c.getCacheFilePath(netName, rt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil {
|
if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ioutil.WriteFile(fname, data, 0600)
|
|
||||||
|
return ioutil.WriteFile(fname, newBytes, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
func delCachedResult(netName string, rt *RuntimeConf) error {
|
func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error {
|
||||||
fname := getResultCacheFilePath(netName, rt)
|
fname, err := c.getCacheFilePath(netName, rt)
|
||||||
|
if err != nil {
|
||||||
|
// Ignore error
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return os.Remove(fname)
|
return os.Remove(fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||||
fname := getResultCacheFilePath(netName, rt)
|
var bytes []byte
|
||||||
|
|
||||||
|
fname, err := c.getCacheFilePath(netName, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
bytes, err = ioutil.ReadFile(fname)
|
||||||
|
if err != nil {
|
||||||
|
// Ignore read errors; the cached result may not exist on-disk
|
||||||
|
return nil, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
unmarshaled := cachedInfo{}
|
||||||
|
if err := json.Unmarshal(bytes, &unmarshaled); err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failed to unmarshal cached network %q config: %v", netName, err)
|
||||||
|
}
|
||||||
|
if unmarshaled.Kind != CNICacheV1 {
|
||||||
|
return nil, nil, fmt.Errorf("read cached network %q config has wrong kind: %v", netName, unmarshaled.Kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
newRt := *rt
|
||||||
|
if unmarshaled.CniArgs != nil {
|
||||||
|
newRt.Args = unmarshaled.CniArgs
|
||||||
|
}
|
||||||
|
newRt.CapabilityArgs = unmarshaled.CapabilityArgs
|
||||||
|
|
||||||
|
return unmarshaled.Config, &newRt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
||||||
|
fname, err := c.getCacheFilePath(netName, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
data, err := ioutil.ReadFile(fname)
|
data, err := ioutil.ReadFile(fname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Ignore read errors; the cached result may not exist on-disk
|
// Ignore read errors; the cached result may not exist on-disk
|
||||||
@ -222,16 +328,73 @@ func getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result,
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
||||||
|
fname, err := c.getCacheFilePath(netName, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fdata, err := ioutil.ReadFile(fname)
|
||||||
|
if err != nil {
|
||||||
|
// Ignore read errors; the cached result may not exist on-disk
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedInfo := cachedInfo{}
|
||||||
|
if err := json.Unmarshal(fdata, &cachedInfo); err != nil || cachedInfo.Kind != CNICacheV1 {
|
||||||
|
return c.getLegacyCachedResult(netName, cniVersion, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
newBytes, err := json.Marshal(&cachedInfo.RawResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to marshal cached network %q config: %v", netName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the version of the cached result
|
||||||
|
decoder := version.ConfigDecoder{}
|
||||||
|
resultCniVersion, err := decoder.Decode(newBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we can understand the result
|
||||||
|
result, err := version.NewResult(resultCniVersion, newBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to the config version to ensure plugins get prevResult
|
||||||
|
// in the same version as the config. The cached result version
|
||||||
|
// should match the config version unless the config was changed
|
||||||
|
// while the container was running.
|
||||||
|
result, err = result.GetAsVersion(cniVersion)
|
||||||
|
if err != nil && resultCniVersion != cniVersion {
|
||||||
|
return nil, fmt.Errorf("failed to convert cached result version %q to config version %q: %v", resultCniVersion, cniVersion, err)
|
||||||
|
}
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// GetNetworkListCachedResult returns the cached Result of the previous
|
// GetNetworkListCachedResult returns the cached Result of the previous
|
||||||
// previous AddNetworkList() operation for a network list, or an error.
|
// AddNetworkList() operation for a network list, or an error.
|
||||||
func (c *CNIConfig) GetNetworkListCachedResult(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
func (c *CNIConfig) GetNetworkListCachedResult(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
|
||||||
return getCachedResult(list.Name, list.CNIVersion, rt)
|
return c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNetworkCachedResult returns the cached Result of the previous
|
// GetNetworkCachedResult returns the cached Result of the previous
|
||||||
// previous AddNetwork() operation for a network, or an error.
|
// AddNetwork() operation for a network, or an error.
|
||||||
func (c *CNIConfig) GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
func (c *CNIConfig) GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
|
||||||
return getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
return c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNetworkListCachedConfig copies the input RuntimeConf to output
|
||||||
|
// RuntimeConf with fields updated with info from the cached Config.
|
||||||
|
func (c *CNIConfig) GetNetworkListCachedConfig(list *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||||
|
return c.getCachedConfig(list.Name, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNetworkCachedConfig copies the input RuntimeConf to output
|
||||||
|
// RuntimeConf with fields updated with info from the cached Config.
|
||||||
|
func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||||
|
return c.getCachedConfig(net.Network.Name, rt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
|
func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
|
||||||
@ -240,6 +403,15 @@ func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := utils.ValidateContainerID(rt.ContainerID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := utils.ValidateNetworkName(name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := utils.ValidateInterfaceName(rt.IfName); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -260,7 +432,7 @@ func (c *CNIConfig) AddNetworkList(ctx context.Context, list *NetworkConfigList,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = setCachedResult(result, list.Name, rt); err != nil {
|
if err = c.cacheAdd(result, list.Bytes, list.Name, rt); err != nil {
|
||||||
return nil, fmt.Errorf("failed to set network %q cached result: %v", list.Name, err)
|
return nil, fmt.Errorf("failed to set network %q cached result: %v", list.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +467,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedResult, err := getCachedResult(list.Name, list.CNIVersion, rt)
|
cachedResult, err := c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
||||||
}
|
}
|
||||||
@ -332,7 +504,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
|
|||||||
if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
|
if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if gtet {
|
} else if gtet {
|
||||||
cachedResult, err = getCachedResult(list.Name, list.CNIVersion, rt)
|
cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
||||||
}
|
}
|
||||||
@ -344,7 +516,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = delCachedResult(list.Name, rt)
|
_ = c.cacheDel(list.Name, rt)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -356,7 +528,7 @@ func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = setCachedResult(result, net.Network.Name, rt); err != nil {
|
if err = c.cacheAdd(result, net.Bytes, net.Network.Name, rt); err != nil {
|
||||||
return nil, fmt.Errorf("failed to set network %q cached result: %v", net.Network.Name, err)
|
return nil, fmt.Errorf("failed to set network %q cached result: %v", net.Network.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +544,7 @@ func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *Ru
|
|||||||
return fmt.Errorf("configuration version %q does not support the CHECK command", net.Network.CNIVersion)
|
return fmt.Errorf("configuration version %q does not support the CHECK command", net.Network.CNIVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedResult, err := getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
||||||
}
|
}
|
||||||
@ -387,7 +559,7 @@ func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
|
|||||||
if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
|
if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if gtet {
|
} else if gtet {
|
||||||
cachedResult, err = getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
cachedResult, err = c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
||||||
}
|
}
|
||||||
@ -396,7 +568,7 @@ func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
|
|||||||
if err := c.delNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt); err != nil {
|
if err := c.delNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_ = delCachedResult(net.Network.Name, rt)
|
_ = c.cacheDel(net.Network.Name, rt)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,10 +627,14 @@ func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]
|
|||||||
|
|
||||||
// validatePlugin checks that an individual plugin's configuration is sane
|
// validatePlugin checks that an individual plugin's configuration is sane
|
||||||
func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVersion string) error {
|
func (c *CNIConfig) validatePlugin(ctx context.Context, pluginName, expectedVersion string) error {
|
||||||
pluginPath, err := invoke.FindInPath(pluginName, c.Path)
|
c.ensureExec()
|
||||||
|
pluginPath, err := c.exec.FindInPath(pluginName, c.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if expectedVersion == "" {
|
||||||
|
expectedVersion = "0.1.0"
|
||||||
|
}
|
||||||
|
|
||||||
vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec)
|
vi, err := invoke.GetVersionInfo(ctx, pluginPath, c.exec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
4
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
4
vendor/github.com/containernetworking/cni/libcni/conf.go
generated
vendored
@ -114,11 +114,11 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
|
|||||||
for i, conf := range plugins {
|
for i, conf := range plugins {
|
||||||
newBytes, err := json.Marshal(conf)
|
newBytes, err := json.Marshal(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to marshal plugin config %d: %v", i, err)
|
return nil, fmt.Errorf("failed to marshal plugin config %d: %v", i, err)
|
||||||
}
|
}
|
||||||
netConf, err := ConfFromBytes(newBytes)
|
netConf, err := ConfFromBytes(newBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to parse plugin config %d: %v", i, err)
|
return nil, fmt.Errorf("failed to parse plugin config %d: %v", i, err)
|
||||||
}
|
}
|
||||||
list.Plugins = append(list.Plugins, netConf)
|
list.Plugins = append(list.Plugins, netConf)
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
6
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
@ -32,7 +32,7 @@ type inherited struct{}
|
|||||||
|
|
||||||
var inheritArgsFromEnv inherited
|
var inheritArgsFromEnv inherited
|
||||||
|
|
||||||
func (_ *inherited) AsEnv() []string {
|
func (*inherited) AsEnv() []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ func (args *Args) AsEnv() []string {
|
|||||||
pluginArgsStr = stringify(args.PluginArgs)
|
pluginArgsStr = stringify(args.PluginArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicated values which come first will be overrided, so we must put the
|
// Duplicated values which come first will be overridden, so we must put the
|
||||||
// custom values in the end to avoid being overrided by the process environments.
|
// custom values in the end to avoid being overridden by the process environments.
|
||||||
env = append(env,
|
env = append(env,
|
||||||
"CNI_COMMAND="+args.Command,
|
"CNI_COMMAND="+args.Command,
|
||||||
"CNI_CONTAINERID="+args.ContainerID,
|
"CNI_CONTAINERID="+args.ContainerID,
|
||||||
|
50
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
50
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
@ -21,6 +21,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
)
|
)
|
||||||
@ -31,32 +33,56 @@ type RawExec struct {
|
|||||||
|
|
||||||
func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
|
||||||
stdout := &bytes.Buffer{}
|
stdout := &bytes.Buffer{}
|
||||||
|
stderr := &bytes.Buffer{}
|
||||||
c := exec.CommandContext(ctx, pluginPath)
|
c := exec.CommandContext(ctx, pluginPath)
|
||||||
c.Env = environ
|
c.Env = environ
|
||||||
c.Stdin = bytes.NewBuffer(stdinData)
|
c.Stdin = bytes.NewBuffer(stdinData)
|
||||||
c.Stdout = stdout
|
c.Stdout = stdout
|
||||||
c.Stderr = e.Stderr
|
c.Stderr = stderr
|
||||||
if err := c.Run(); err != nil {
|
|
||||||
return nil, pluginErr(err, stdout.Bytes())
|
// Retry the command on "text file busy" errors
|
||||||
|
for i := 0; i <= 5; i++ {
|
||||||
|
err := c.Run()
|
||||||
|
|
||||||
|
// Command succeeded
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the plugin is currently about to be written, then we wait a
|
||||||
|
// second and try it again
|
||||||
|
if strings.Contains(err.Error(), "text file busy") {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other errors except than the busy text file
|
||||||
|
return nil, e.pluginErr(err, stdout.Bytes(), stderr.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy stderr to caller's buffer in case plugin printed to both
|
||||||
|
// stdout and stderr for some reason. Ignore failures as stderr is
|
||||||
|
// only informational.
|
||||||
|
if e.Stderr != nil && stderr.Len() > 0 {
|
||||||
|
_, _ = stderr.WriteTo(e.Stderr)
|
||||||
|
}
|
||||||
return stdout.Bytes(), nil
|
return stdout.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func pluginErr(err error, output []byte) error {
|
func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error {
|
||||||
if _, ok := err.(*exec.ExitError); ok {
|
|
||||||
emsg := types.Error{}
|
emsg := types.Error{}
|
||||||
if len(output) == 0 {
|
if len(stdout) == 0 {
|
||||||
emsg.Msg = "netplugin failed with no error message"
|
if len(stderr) == 0 {
|
||||||
} else if perr := json.Unmarshal(output, &emsg); perr != nil {
|
emsg.Msg = fmt.Sprintf("netplugin failed with no error message: %v", err)
|
||||||
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
|
} else {
|
||||||
|
emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(stderr))
|
||||||
|
}
|
||||||
|
} else if perr := json.Unmarshal(stdout, &emsg); perr != nil {
|
||||||
|
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(stdout), perr)
|
||||||
}
|
}
|
||||||
return &emsg
|
return &emsg
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) {
|
func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) {
|
||||||
return FindInPath(plugin, paths)
|
return FindInPath(plugin, paths)
|
||||||
}
|
}
|
||||||
|
99
vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
99
vendor/github.com/containernetworking/cni/pkg/skel/skel.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
"github.com/containernetworking/cni/pkg/utils"
|
||||||
"github.com/containernetworking/cni/pkg/version"
|
"github.com/containernetworking/cni/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,16 +54,7 @@ type dispatcher struct {
|
|||||||
|
|
||||||
type reqForCmdEntry map[string]bool
|
type reqForCmdEntry map[string]bool
|
||||||
|
|
||||||
// internal only error to indicate lack of required environment variables
|
func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
|
||||||
type missingEnvError struct {
|
|
||||||
msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e missingEnvError) Error() string {
|
|
||||||
return e.msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) {
|
|
||||||
var cmd, contID, netns, ifName, args, path string
|
var cmd, contID, netns, ifName, args, path string
|
||||||
|
|
||||||
vars := []struct {
|
vars := []struct {
|
||||||
@ -138,7 +130,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) {
|
|||||||
|
|
||||||
if len(argsMissing) > 0 {
|
if len(argsMissing) > 0 {
|
||||||
joined := strings.Join(argsMissing, ",")
|
joined := strings.Join(argsMissing, ",")
|
||||||
return "", nil, missingEnvError{fmt.Sprintf("required env variables [%s] missing", joined)}
|
return "", nil, types.NewError(types.ErrInvalidEnvironmentVariables, fmt.Sprintf("required env variables [%s] missing", joined), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd == "VERSION" {
|
if cmd == "VERSION" {
|
||||||
@ -147,7 +139,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) {
|
|||||||
|
|
||||||
stdinData, err := ioutil.ReadAll(t.Stdin)
|
stdinData, err := ioutil.ReadAll(t.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, fmt.Errorf("error reading from stdin: %v", err)
|
return "", nil, types.NewError(types.ErrIOFailure, fmt.Sprintf("error reading from stdin: %v", err), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdArgs := &CmdArgs{
|
cmdArgs := &CmdArgs{
|
||||||
@ -161,39 +153,39 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) {
|
|||||||
return cmd, cmdArgs, nil
|
return cmd, cmdArgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTypedError(f string, args ...interface{}) *types.Error {
|
func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo version.PluginInfo, toCall func(*CmdArgs) error) *types.Error {
|
||||||
return &types.Error{
|
|
||||||
Code: 100,
|
|
||||||
Msg: fmt.Sprintf(f, args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo version.PluginInfo, toCall func(*CmdArgs) error) error {
|
|
||||||
configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
|
configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return types.NewError(types.ErrDecodingFailure, err.Error(), "")
|
||||||
}
|
}
|
||||||
verErr := t.VersionReconciler.Check(configVersion, pluginVersionInfo)
|
verErr := t.VersionReconciler.Check(configVersion, pluginVersionInfo)
|
||||||
if verErr != nil {
|
if verErr != nil {
|
||||||
return &types.Error{
|
return types.NewError(types.ErrIncompatibleCNIVersion, "incompatible CNI versions", verErr.Details())
|
||||||
Code: types.ErrIncompatibleCNIVersion,
|
|
||||||
Msg: "incompatible CNI versions",
|
|
||||||
Details: verErr.Details(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return toCall(cmdArgs)
|
if err = toCall(cmdArgs); err != nil {
|
||||||
|
if e, ok := err.(*types.Error); ok {
|
||||||
|
// don't wrap Error in Error
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
return types.NewError(types.ErrInternal, err.Error(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateConfig(jsonBytes []byte) error {
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateConfig(jsonBytes []byte) *types.Error {
|
||||||
var conf struct {
|
var conf struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(jsonBytes, &conf); err != nil {
|
if err := json.Unmarshal(jsonBytes, &conf); err != nil {
|
||||||
return fmt.Errorf("error reading network config: %s", err)
|
return types.NewError(types.ErrDecodingFailure, fmt.Sprintf("error unmarshall network config: %v", err), "")
|
||||||
}
|
}
|
||||||
if conf.Name == "" {
|
if conf.Name == "" {
|
||||||
return fmt.Errorf("missing network name")
|
return types.NewError(types.ErrInvalidNetworkConfig, "missing network name", "")
|
||||||
|
}
|
||||||
|
if err := utils.ValidateNetworkName(conf.Name); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -202,17 +194,22 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
|||||||
cmd, cmdArgs, err := t.getCmdArgsFromEnv()
|
cmd, cmdArgs, err := t.getCmdArgsFromEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Print the about string to stderr when no command is set
|
// Print the about string to stderr when no command is set
|
||||||
if _, ok := err.(missingEnvError); ok && t.Getenv("CNI_COMMAND") == "" && about != "" {
|
if err.Code == types.ErrInvalidEnvironmentVariables && t.Getenv("CNI_COMMAND") == "" && about != "" {
|
||||||
fmt.Fprintln(t.Stderr, about)
|
_, _ = fmt.Fprintln(t.Stderr, about)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return createTypedError(err.Error())
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd != "VERSION" {
|
if cmd != "VERSION" {
|
||||||
err = validateConfig(cmdArgs.StdinData)
|
if err = validateConfig(cmdArgs.StdinData); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return createTypedError(err.Error())
|
}
|
||||||
|
if err = utils.ValidateContainerID(cmdArgs.ContainerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = utils.ValidateInterfaceName(cmdArgs.IfName); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,45 +219,37 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
|
|||||||
case "CHECK":
|
case "CHECK":
|
||||||
configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
|
configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createTypedError(err.Error())
|
return types.NewError(types.ErrDecodingFailure, err.Error(), "")
|
||||||
}
|
}
|
||||||
if gtet, err := version.GreaterThanOrEqualTo(configVersion, "0.4.0"); err != nil {
|
if gtet, err := version.GreaterThanOrEqualTo(configVersion, "0.4.0"); err != nil {
|
||||||
return createTypedError(err.Error())
|
return types.NewError(types.ErrDecodingFailure, err.Error(), "")
|
||||||
} else if !gtet {
|
} else if !gtet {
|
||||||
return &types.Error{
|
return types.NewError(types.ErrIncompatibleCNIVersion, "config version does not allow CHECK", "")
|
||||||
Code: types.ErrIncompatibleCNIVersion,
|
|
||||||
Msg: "config version does not allow CHECK",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, pluginVersion := range versionInfo.SupportedVersions() {
|
for _, pluginVersion := range versionInfo.SupportedVersions() {
|
||||||
gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion)
|
gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createTypedError(err.Error())
|
return types.NewError(types.ErrDecodingFailure, err.Error(), "")
|
||||||
} else if gtet {
|
} else if gtet {
|
||||||
if err := t.checkVersionAndCall(cmdArgs, versionInfo, cmdCheck); err != nil {
|
if err := t.checkVersionAndCall(cmdArgs, versionInfo, cmdCheck); err != nil {
|
||||||
return createTypedError(err.Error())
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &types.Error{
|
return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow CHECK", "")
|
||||||
Code: types.ErrIncompatibleCNIVersion,
|
|
||||||
Msg: "plugin version does not allow CHECK",
|
|
||||||
}
|
|
||||||
case "DEL":
|
case "DEL":
|
||||||
err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel)
|
err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel)
|
||||||
case "VERSION":
|
case "VERSION":
|
||||||
err = versionInfo.Encode(t.Stdout)
|
if err := versionInfo.Encode(t.Stdout); err != nil {
|
||||||
|
return types.NewError(types.ErrIOFailure, err.Error(), "")
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return createTypedError("unknown CNI_COMMAND: %v", cmd)
|
return types.NewError(types.ErrInvalidEnvironmentVariables, fmt.Sprintf("unknown CNI_COMMAND: %v", cmd), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*types.Error); ok {
|
return err
|
||||||
// don't wrap Error in Error
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
return createTypedError(err.Error())
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
14
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
14
vendor/github.com/containernetworking/cni/pkg/types/020/types.go
generated
vendored
@ -86,20 +86,6 @@ func (r *Result) PrintTo(writer io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where
|
|
||||||
// $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the
|
|
||||||
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
|
||||||
func (r *Result) String() string {
|
|
||||||
var str string
|
|
||||||
if r.IP4 != nil {
|
|
||||||
str = fmt.Sprintf("IP4:%+v, ", *r.IP4)
|
|
||||||
}
|
|
||||||
if r.IP6 != nil {
|
|
||||||
str += fmt.Sprintf("IP6:%+v, ", *r.IP6)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IPConfig contains values necessary to configure an interface
|
// IPConfig contains values necessary to configure an interface
|
||||||
type IPConfig struct {
|
type IPConfig struct {
|
||||||
IP net.IPNet
|
IP net.IPNet
|
||||||
|
2
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
2
vendor/github.com/containernetworking/cni/pkg/types/args.go
generated
vendored
@ -36,7 +36,7 @@ func (b *UnmarshallableBool) UnmarshalText(data []byte) error {
|
|||||||
case "0", "false":
|
case "0", "false":
|
||||||
*b = false
|
*b = false
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Boolean unmarshal error: invalid input %s", s)
|
return fmt.Errorf("boolean unmarshal error: invalid input %s", s)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
17
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
17
vendor/github.com/containernetworking/cni/pkg/types/current/types.go
generated
vendored
@ -207,23 +207,6 @@ func (r *Result) PrintTo(writer io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a formatted string in the form of "[Interfaces: $1,][ IP: $2,] DNS: $3" where
|
|
||||||
// $1 represents the receiver's Interfaces, $2 represents the receiver's IP addresses and $3 the
|
|
||||||
// receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string.
|
|
||||||
func (r *Result) String() string {
|
|
||||||
var str string
|
|
||||||
if len(r.Interfaces) > 0 {
|
|
||||||
str += fmt.Sprintf("Interfaces:%+v, ", r.Interfaces)
|
|
||||||
}
|
|
||||||
if len(r.IPs) > 0 {
|
|
||||||
str += fmt.Sprintf("IP:%+v, ", r.IPs)
|
|
||||||
}
|
|
||||||
if len(r.Routes) > 0 {
|
|
||||||
str += fmt.Sprintf("Routes:%+v, ", r.Routes)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%sDNS:%+v", str, r.DNS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert this old version result to the current CNI version result
|
// Convert this old version result to the current CNI version result
|
||||||
func (r *Result) Convert() (*Result, error) {
|
func (r *Result) Convert() (*Result, error) {
|
||||||
return r, nil
|
return r, nil
|
||||||
|
22
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
22
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
@ -16,7 +16,6 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -101,9 +100,6 @@ type Result interface {
|
|||||||
|
|
||||||
// Prints the result in JSON format to provided writer
|
// Prints the result in JSON format to provided writer
|
||||||
PrintTo(writer io.Writer) error
|
PrintTo(writer io.Writer) error
|
||||||
|
|
||||||
// Returns a JSON string representation of the result
|
|
||||||
String() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrintResult(result Result, version string) error {
|
func PrintResult(result Result, version string) error {
|
||||||
@ -137,6 +133,13 @@ const (
|
|||||||
ErrUnknown uint = iota // 0
|
ErrUnknown uint = iota // 0
|
||||||
ErrIncompatibleCNIVersion // 1
|
ErrIncompatibleCNIVersion // 1
|
||||||
ErrUnsupportedField // 2
|
ErrUnsupportedField // 2
|
||||||
|
ErrUnknownContainer // 3
|
||||||
|
ErrInvalidEnvironmentVariables // 4
|
||||||
|
ErrIOFailure // 5
|
||||||
|
ErrDecodingFailure // 6
|
||||||
|
ErrInvalidNetworkConfig // 7
|
||||||
|
ErrTryAgainLater uint = 11
|
||||||
|
ErrInternal uint = 999
|
||||||
)
|
)
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
@ -145,6 +148,14 @@ type Error struct {
|
|||||||
Details string `json:"details,omitempty"`
|
Details string `json:"details,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewError(code uint, msg, details string) *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: code,
|
||||||
|
Msg: msg,
|
||||||
|
Details: details,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
func (e *Error) Error() string {
|
||||||
details := ""
|
details := ""
|
||||||
if e.Details != "" {
|
if e.Details != "" {
|
||||||
@ -194,6 +205,3 @@ func prettyPrint(obj interface{}) error {
|
|||||||
_, err = os.Stdout.Write(data)
|
_, err = os.Stdout.Write(data)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotImplementedError is used to indicate that a method is not implemented for the given platform
|
|
||||||
var NotImplementedError = errors.New("Not Implemented")
|
|
||||||
|
84
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
84
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright 2019 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 utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// cniValidNameChars is the regexp used to validate valid characters in
|
||||||
|
// containerID and networkName
|
||||||
|
cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
|
||||||
|
|
||||||
|
// maxInterfaceNameLength is the length max of a valid interface name
|
||||||
|
maxInterfaceNameLength = 15
|
||||||
|
)
|
||||||
|
|
||||||
|
var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`)
|
||||||
|
|
||||||
|
// ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters
|
||||||
|
func ValidateContainerID(containerID string) *types.Error {
|
||||||
|
|
||||||
|
if containerID == "" {
|
||||||
|
return types.NewError(types.ErrUnknownContainer, "missing containerID", "")
|
||||||
|
}
|
||||||
|
if !cniReg.MatchString(containerID) {
|
||||||
|
return types.NewError(types.ErrInvalidEnvironmentVariables, "invalid characters in containerID", containerID)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateNetworkName will validate that the supplied networkName does not contain invalid characters
|
||||||
|
func ValidateNetworkName(networkName string) *types.Error {
|
||||||
|
|
||||||
|
if networkName == "" {
|
||||||
|
return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "")
|
||||||
|
}
|
||||||
|
if !cniReg.MatchString(networkName) {
|
||||||
|
return types.NewError(types.ErrInvalidNetworkConfig, "invalid characters found in network name", networkName)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateInterfaceName will validate the interface name based on the three rules below
|
||||||
|
// 1. The name must not be empty
|
||||||
|
// 2. The name must be less than 16 characters
|
||||||
|
// 3. The name must not be "." or ".."
|
||||||
|
// 3. The name must not contain / or : or any whitespace characters
|
||||||
|
// ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024
|
||||||
|
func ValidateInterfaceName(ifName string) *types.Error {
|
||||||
|
if len(ifName) == 0 {
|
||||||
|
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is empty", "")
|
||||||
|
}
|
||||||
|
if len(ifName) > maxInterfaceNameLength {
|
||||||
|
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is too long", fmt.Sprintf("interface name should be less than %d characters", maxInterfaceNameLength+1))
|
||||||
|
}
|
||||||
|
if ifName == "." || ifName == ".." {
|
||||||
|
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name is . or ..", "")
|
||||||
|
}
|
||||||
|
for _, r := range bytes.Runes([]byte(ifName)) {
|
||||||
|
if r == '/' || r == ':' || unicode.IsSpace(r) {
|
||||||
|
return types.NewError(types.ErrInvalidEnvironmentVariables, "interface name contains / or : or whitespace characters", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@ -28,7 +28,7 @@ github.com/alexflint/go-filemutex
|
|||||||
# github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
# github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44
|
||||||
## explicit
|
## explicit
|
||||||
github.com/buger/jsonparser
|
github.com/buger/jsonparser
|
||||||
# github.com/containernetworking/cni v0.7.1
|
# github.com/containernetworking/cni v0.8.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/containernetworking/cni/libcni
|
github.com/containernetworking/cni/libcni
|
||||||
github.com/containernetworking/cni/pkg/invoke
|
github.com/containernetworking/cni/pkg/invoke
|
||||||
@ -36,6 +36,7 @@ github.com/containernetworking/cni/pkg/skel
|
|||||||
github.com/containernetworking/cni/pkg/types
|
github.com/containernetworking/cni/pkg/types
|
||||||
github.com/containernetworking/cni/pkg/types/020
|
github.com/containernetworking/cni/pkg/types/020
|
||||||
github.com/containernetworking/cni/pkg/types/current
|
github.com/containernetworking/cni/pkg/types/current
|
||||||
|
github.com/containernetworking/cni/pkg/utils
|
||||||
github.com/containernetworking/cni/pkg/version
|
github.com/containernetworking/cni/pkg/version
|
||||||
# github.com/coreos/go-iptables v0.4.5
|
# github.com/coreos/go-iptables v0.4.5
|
||||||
## explicit
|
## explicit
|
||||||
|
Reference in New Issue
Block a user