mirror of
https://github.com/containers/podman.git
synced 2025-10-18 03:33:32 +08:00
Merge pull request #4007 from mccv1r0/v1.4.1-crio114
libpod vendor update for CNI and ocicni
This commit is contained in:
@ -11,7 +11,6 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
types2 "github.com/containernetworking/cni/pkg/types"
|
||||
cp "github.com/containers/image/copy"
|
||||
"github.com/containers/image/directory"
|
||||
dockerarchive "github.com/containers/image/docker/archive"
|
||||
@ -389,11 +388,6 @@ func (i *Image) Remove(ctx context.Context, force bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decompose an Image
|
||||
func (i *Image) Decompose() error {
|
||||
return types2.NotImplementedError
|
||||
}
|
||||
|
||||
// TODO: Rework this method to not require an assembly of the fq name with transport
|
||||
/*
|
||||
// GetManifest tries to GET an images manifest, returns nil on success and err on failure
|
||||
|
@ -27,25 +27,36 @@ import (
|
||||
)
|
||||
|
||||
// Get an OCICNI network config
|
||||
func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, ports []ocicni.PortMapping, staticIP net.IP) ocicni.PodNetwork {
|
||||
network := ocicni.PodNetwork{
|
||||
Name: name,
|
||||
Namespace: name, // TODO is there something else we should put here? We don't know about Kube namespaces
|
||||
ID: id,
|
||||
NetNS: nsPath,
|
||||
PortMappings: ports,
|
||||
Networks: networks,
|
||||
func (r *Runtime) getPodNetwork(id, name, nsPath string, config *ContainerConfig, staticIP net.IP) ocicni.PodNetwork {
|
||||
networks := make([]ocicni.NetAttachment, 0)
|
||||
for _, netName := range config.Networks {
|
||||
networks = append(networks, ocicni.NetAttachment{Name: netName})
|
||||
}
|
||||
if len(networks) == 0 {
|
||||
networks = append(networks, ocicni.NetAttachment{Name: r.netPlugin.GetDefaultNetworkName()})
|
||||
}
|
||||
|
||||
firstNetworkName := networks[0].Name
|
||||
podNetwork := ocicni.PodNetwork{
|
||||
Name: name,
|
||||
Namespace: name, // TODO is there something else we should put here? We don't know about Kube namespaces
|
||||
ID: id,
|
||||
NetNS: nsPath,
|
||||
Networks: networks,
|
||||
RuntimeConfig: map[string]ocicni.RuntimeConfig{
|
||||
firstNetworkName: {},
|
||||
},
|
||||
}
|
||||
firstNetwork := podNetwork.RuntimeConfig[firstNetworkName]
|
||||
if len(config.PortMappings) != 0 {
|
||||
firstNetwork.PortMappings = config.PortMappings
|
||||
}
|
||||
if staticIP != nil {
|
||||
defaultNetwork := r.netPlugin.GetDefaultNetworkName()
|
||||
|
||||
network.Networks = []string{defaultNetwork}
|
||||
network.NetworkConfig = make(map[string]ocicni.NetworkConfig)
|
||||
network.NetworkConfig[defaultNetwork] = ocicni.NetworkConfig{IP: staticIP.String()}
|
||||
firstNetwork.IP = staticIP.String()
|
||||
}
|
||||
podNetwork.RuntimeConfig[firstNetworkName] = firstNetwork
|
||||
|
||||
return network
|
||||
return podNetwork
|
||||
}
|
||||
|
||||
// Create and configure a new network namespace for a container
|
||||
@ -59,7 +70,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
|
||||
requestedIP = ctr.config.StaticIP
|
||||
}
|
||||
|
||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
|
||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.Config(), requestedIP)
|
||||
|
||||
results, err := r.netPlugin.SetUpPod(podNetwork)
|
||||
if err != nil {
|
||||
@ -75,10 +86,10 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
|
||||
|
||||
networkStatus := make([]*cnitypes.Result, 0)
|
||||
for idx, r := range results {
|
||||
logrus.Debugf("[%d] CNI result: %v", idx, r.String())
|
||||
resultCurrent, err := cnitypes.GetResult(r)
|
||||
logrus.Debugf("[%d] CNI result: %v", idx, r.Result)
|
||||
resultCurrent, err := cnitypes.GetResult(r.Result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.String(), err)
|
||||
return nil, errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.Result, err)
|
||||
}
|
||||
networkStatus = append(networkStatus, resultCurrent)
|
||||
}
|
||||
@ -408,7 +419,7 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||
requestedIP = ctr.config.StaticIP
|
||||
}
|
||||
|
||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
|
||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.Config(), requestedIP)
|
||||
|
||||
// The network may have already been torn down, so don't fail here, just log
|
||||
if err := r.netPlugin.TearDownPod(podNetwork); err != nil {
|
||||
|
@ -13,7 +13,7 @@ github.com/buger/goterm c206103e1f37c0c6c5c039706305ea2aa6e8ad3b
|
||||
github.com/checkpoint-restore/go-criu v3.11
|
||||
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
||||
github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d
|
||||
github.com/containernetworking/cni v0.7.0-rc2
|
||||
github.com/containernetworking/cni 83439463f7840005184ec4c488c9edd6ed6978fc
|
||||
github.com/containernetworking/plugins v0.7.4
|
||||
github.com/containers/image v2.0.0
|
||||
github.com/vbauerster/mpb v3.3.4
|
||||
@ -23,7 +23,7 @@ github.com/containers/storage v1.12.10
|
||||
github.com/containers/psgo v1.3.0
|
||||
github.com/coreos/go-systemd v17
|
||||
github.com/coreos/pkg v4
|
||||
github.com/cri-o/ocicni 0c180f981b27ef6036fa5be29bcb4dd666e406eb
|
||||
github.com/cri-o/ocicni 7bd73e9a7f59107c76605aecd2c8ec3d69ef3ff8
|
||||
github.com/cyphar/filepath-securejoin v0.2.1
|
||||
github.com/davecgh/go-spew v1.1.0
|
||||
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
|
||||
|
8
vendor/github.com/containernetworking/cni/README.md
generated
vendored
8
vendor/github.com/containernetworking/cni/README.md
generated
vendored
@ -9,7 +9,7 @@
|
||||
|
||||
# Community Sync Meeting
|
||||
|
||||
There is a community sync meeting for users and developers every 1-2 months. The next meeting will help on a Google Hangout and the link is in the [agenda](https://docs.google.com/document/d/10ECyT2mBGewsJUcmYmS8QNo1AcNgy2ZIe2xS7lShYhE/edit?usp=sharing) (Notes from previous meeting are also in this doc).
|
||||
There is a community sync meeting for users and developers every 1-2 months. The next meeting will be held on a Google Hangout and the link is in the [agenda](https://docs.google.com/document/d/10ECyT2mBGewsJUcmYmS8QNo1AcNgy2ZIe2xS7lShYhE/edit?usp=sharing) (Notes from previous meeting are also in this doc).
|
||||
|
||||
The next meeting will be held on *Wednesday, January 30th, 2019* at *4:00pm UTC / 11:00am EDT / 8:00am PDT* [Add to Calendar](https://www.worldtimebuddy.com/?qm=1&lid=100,5,2643743,5391959&h=100&date=2019-01-30&sln=16-17).
|
||||
|
||||
@ -67,6 +67,8 @@ To avoid duplication, we think it is prudent to define a common interface betwee
|
||||
- [Knitter - a CNI plugin supporting multiple networking for Kubernetes](https://github.com/ZTE/Knitter)
|
||||
- [DANM - a CNI-compliant networking solution for TelCo workloads running on Kubernetes](https://github.com/nokia/danm)
|
||||
- [VMware NSX – a CNI plugin that enables automated NSX L2/L3 networking and L4/L7 Load Balancing; network isolation at the pod, node, and cluster level; and zero-trust security policy for your Kubernetes cluster.](https://docs.vmware.com/en/VMware-NSX-T/2.2/com.vmware.nsxt.ncp_kubernetes.doc/GUID-6AFA724E-BB62-4693-B95C-321E8DDEA7E1.html)
|
||||
- [cni-route-override - a meta CNI plugin that override route information](https://github.com/redhat-nfvpe/cni-route-override)
|
||||
- [Terway - a collection of CNI Plugins based on alibaba cloud VPC/ECS network product](https://github.com/AliyunContainerService/terway)
|
||||
|
||||
The CNI team also maintains some [core plugins in a separate repository](https://github.com/containernetworking/plugins).
|
||||
|
||||
@ -189,13 +191,13 @@ lo Link encap:Local Loopback
|
||||
|
||||
## What might CNI do in the future?
|
||||
|
||||
CNI currently covers a wide range of needs for network configuration due to it simple model and API.
|
||||
CNI currently covers a wide range of needs for network configuration due to its simple model and API.
|
||||
However, in the future CNI might want to branch out into other directions:
|
||||
|
||||
- Dynamic updates to existing network configuration
|
||||
- Dynamic policies for network bandwidth and firewall rules
|
||||
|
||||
If these topics of are interest, please contact the team via the mailing list or IRC and find some like-minded people in the community to put a proposal together.
|
||||
If these topics are of interest, please contact the team via the mailing list or IRC and find some like-minded people in the community to put a proposal together.
|
||||
|
||||
## Contact
|
||||
|
||||
|
233
vendor/github.com/containernetworking/cni/libcni/api.go
generated
vendored
233
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/types"
|
||||
"github.com/containernetworking/cni/pkg/utils"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
)
|
||||
|
||||
@ -32,6 +33,10 @@ var (
|
||||
CacheDir = "/var/lib/cni"
|
||||
)
|
||||
|
||||
const (
|
||||
CNICacheV1 = "cniCacheV1"
|
||||
)
|
||||
|
||||
// A RuntimeConf holds the arguments to one invocation of a CNI plugin
|
||||
// excepting the network configuration, with the nested exception that
|
||||
// the `runtimeConfig` from the network configuration is included
|
||||
@ -48,7 +53,7 @@ type RuntimeConf struct {
|
||||
// to the plugin
|
||||
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
|
||||
}
|
||||
|
||||
@ -69,19 +74,23 @@ type CNI interface {
|
||||
AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
|
||||
CheckNetworkList(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)
|
||||
GetNetworkListCachedConfig(net *NetworkConfigList, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||
|
||||
AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
|
||||
CheckNetwork(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)
|
||||
GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
|
||||
|
||||
ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
|
||||
ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
|
||||
}
|
||||
|
||||
type CNIConfig struct {
|
||||
Path []string
|
||||
exec invoke.Exec
|
||||
Path []string
|
||||
exec invoke.Exec
|
||||
cacheDir string
|
||||
}
|
||||
|
||||
// CNIConfig implements the CNI interface
|
||||
@ -91,9 +100,18 @@ var _ CNI = &CNIConfig{}
|
||||
// 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.
|
||||
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{
|
||||
Path: path,
|
||||
exec: exec,
|
||||
Path: path,
|
||||
cacheDir: cacheDir,
|
||||
exec: exec,
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,33 +182,122 @@ func (c *CNIConfig) ensureExec() invoke.Exec {
|
||||
return c.exec
|
||||
}
|
||||
|
||||
func getResultCacheFilePath(netName string, rt *RuntimeConf) string {
|
||||
cacheDir := rt.CacheDir
|
||||
if cacheDir == "" {
|
||||
cacheDir = CacheDir
|
||||
}
|
||||
return filepath.Join(cacheDir, "results", fmt.Sprintf("%s-%s-%s", netName, rt.ContainerID, rt.IfName))
|
||||
type cachedInfo struct {
|
||||
Kind string `json:"kind"`
|
||||
ContainerID string `json:"containerId"`
|
||||
Config []byte `json:"config"`
|
||||
IfName string `json:"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)
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(fname, data, 0600)
|
||||
|
||||
return ioutil.WriteFile(fname, newBytes, 0600)
|
||||
}
|
||||
|
||||
func delCachedResult(netName string, rt *RuntimeConf) error {
|
||||
fname := getResultCacheFilePath(netName, rt)
|
||||
func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error {
|
||||
fname, err := c.getCacheFilePath(netName, rt)
|
||||
if err != nil {
|
||||
// Ignore error
|
||||
return nil
|
||||
}
|
||||
return os.Remove(fname)
|
||||
}
|
||||
|
||||
func getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
|
||||
fname := getResultCacheFilePath(netName, rt)
|
||||
func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *RuntimeConf, error) {
|
||||
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)
|
||||
if err != nil {
|
||||
// Ignore read errors; the cached result may not exist on-disk
|
||||
@ -221,16 +328,73 @@ func getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result,
|
||||
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
|
||||
// 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) {
|
||||
return getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
return c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
@ -239,6 +403,12 @@ func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := utils.ValidateContainerID(rt.ContainerID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := utils.ValidateNetworkName(name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt)
|
||||
if err != nil {
|
||||
@ -259,7 +429,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)
|
||||
}
|
||||
|
||||
@ -294,7 +464,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis
|
||||
return nil
|
||||
}
|
||||
|
||||
cachedResult, err := getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
cachedResult, err := c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
||||
}
|
||||
@ -331,7 +501,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
|
||||
if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
|
||||
return err
|
||||
} else if gtet {
|
||||
cachedResult, err = getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
|
||||
}
|
||||
@ -343,7 +513,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
|
||||
return err
|
||||
}
|
||||
}
|
||||
_ = delCachedResult(list.Name, rt)
|
||||
_ = c.cacheDel(list.Name, rt)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -355,7 +525,7 @@ func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
|
||||
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)
|
||||
}
|
||||
|
||||
@ -371,7 +541,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)
|
||||
}
|
||||
|
||||
cachedResult, err := getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||
cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
||||
}
|
||||
@ -386,7 +556,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 {
|
||||
return err
|
||||
} 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 {
|
||||
return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
|
||||
}
|
||||
@ -395,7 +565,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 {
|
||||
return err
|
||||
}
|
||||
_ = delCachedResult(net.Network.Name, rt)
|
||||
_ = c.cacheDel(net.Network.Name, rt)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -454,7 +624,8 @@ func (c *CNIConfig) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]
|
||||
|
||||
// validatePlugin checks that an individual plugin's configuration is sane
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
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 {
|
||||
newBytes, err := json.Marshal(conf)
|
||||
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)
|
||||
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)
|
||||
}
|
||||
|
70
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
70
vendor/github.com/containernetworking/cni/pkg/invoke/args.go
generated
vendored
@ -15,6 +15,7 @@
|
||||
package invoke
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
@ -22,6 +23,8 @@ import (
|
||||
type CNIArgs interface {
|
||||
// For use with os/exec; i.e., return nil to inherit the
|
||||
// environment from this process
|
||||
// For use in delegation; inherit the environment from this
|
||||
// process and allow overrides
|
||||
AsEnv() []string
|
||||
}
|
||||
|
||||
@ -29,7 +32,7 @@ type inherited struct{}
|
||||
|
||||
var inheritArgsFromEnv inherited
|
||||
|
||||
func (_ *inherited) AsEnv() []string {
|
||||
func (*inherited) AsEnv() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -57,17 +60,17 @@ func (args *Args) AsEnv() []string {
|
||||
pluginArgsStr = stringify(args.PluginArgs)
|
||||
}
|
||||
|
||||
// Ensure that the custom values are first, so any value present in
|
||||
// the process environment won't override them.
|
||||
env = append([]string{
|
||||
"CNI_COMMAND=" + args.Command,
|
||||
"CNI_CONTAINERID=" + args.ContainerID,
|
||||
"CNI_NETNS=" + args.NetNS,
|
||||
"CNI_ARGS=" + pluginArgsStr,
|
||||
"CNI_IFNAME=" + args.IfName,
|
||||
"CNI_PATH=" + args.Path,
|
||||
}, env...)
|
||||
return env
|
||||
// Duplicated values which come first will be overrided, so we must put the
|
||||
// custom values in the end to avoid being overrided by the process environments.
|
||||
env = append(env,
|
||||
"CNI_COMMAND="+args.Command,
|
||||
"CNI_CONTAINERID="+args.ContainerID,
|
||||
"CNI_NETNS="+args.NetNS,
|
||||
"CNI_ARGS="+pluginArgsStr,
|
||||
"CNI_IFNAME="+args.IfName,
|
||||
"CNI_PATH="+args.Path,
|
||||
)
|
||||
return dedupEnv(env)
|
||||
}
|
||||
|
||||
// taken from rkt/networking/net_plugin.go
|
||||
@ -80,3 +83,46 @@ func stringify(pluginArgs [][2]string) string {
|
||||
|
||||
return strings.Join(entries, ";")
|
||||
}
|
||||
|
||||
// DelegateArgs implements the CNIArgs interface
|
||||
// used for delegation to inherit from environments
|
||||
// and allow some overrides like CNI_COMMAND
|
||||
var _ CNIArgs = &DelegateArgs{}
|
||||
|
||||
type DelegateArgs struct {
|
||||
Command string
|
||||
}
|
||||
|
||||
func (d *DelegateArgs) AsEnv() []string {
|
||||
env := os.Environ()
|
||||
|
||||
// The custom values should come in the end to override the existing
|
||||
// process environment of the same key.
|
||||
env = append(env,
|
||||
"CNI_COMMAND="+d.Command,
|
||||
)
|
||||
return dedupEnv(env)
|
||||
}
|
||||
|
||||
// dedupEnv returns a copy of env with any duplicates removed, in favor of later values.
|
||||
// Items not of the normal environment "key=value" form are preserved unchanged.
|
||||
func dedupEnv(env []string) []string {
|
||||
out := make([]string, 0, len(env))
|
||||
envMap := map[string]string{}
|
||||
|
||||
for _, kv := range env {
|
||||
// find the first "=" in environment, if not, just keep it
|
||||
eq := strings.Index(kv, "=")
|
||||
if eq < 0 {
|
||||
out = append(out, kv)
|
||||
continue
|
||||
}
|
||||
envMap[kv[:eq]] = kv[eq+1:]
|
||||
}
|
||||
|
||||
for k, v := range envMap {
|
||||
out = append(out, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
29
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
29
vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
generated
vendored
@ -16,22 +16,17 @@ package invoke
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
func delegateCommon(expectedCommand, delegatePlugin string, exec Exec) (string, Exec, error) {
|
||||
func delegateCommon(delegatePlugin string, exec Exec) (string, Exec, error) {
|
||||
if exec == nil {
|
||||
exec = defaultExec
|
||||
}
|
||||
|
||||
if os.Getenv("CNI_COMMAND") != expectedCommand {
|
||||
return "", nil, fmt.Errorf("CNI_COMMAND is not " + expectedCommand)
|
||||
}
|
||||
|
||||
paths := filepath.SplitList(os.Getenv("CNI_PATH"))
|
||||
pluginPath, err := exec.FindInPath(delegatePlugin, paths)
|
||||
if err != nil {
|
||||
@ -44,32 +39,42 @@ func delegateCommon(expectedCommand, delegatePlugin string, exec Exec) (string,
|
||||
// DelegateAdd calls the given delegate plugin with the CNI ADD action and
|
||||
// JSON configuration
|
||||
func DelegateAdd(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) (types.Result, error) {
|
||||
pluginPath, realExec, err := delegateCommon("ADD", delegatePlugin, exec)
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ExecPluginWithResult(ctx, pluginPath, netconf, ArgsFromEnv(), realExec)
|
||||
// DelegateAdd will override the original "CNI_COMMAND" env from process with ADD
|
||||
return ExecPluginWithResult(ctx, pluginPath, netconf, delegateArgs("ADD"), realExec)
|
||||
}
|
||||
|
||||
// DelegateCheck calls the given delegate plugin with the CNI CHECK action and
|
||||
// JSON configuration
|
||||
func DelegateCheck(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
|
||||
pluginPath, realExec, err := delegateCommon("CHECK", delegatePlugin, exec)
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, ArgsFromEnv(), realExec)
|
||||
// DelegateCheck will override the original CNI_COMMAND env from process with CHECK
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("CHECK"), realExec)
|
||||
}
|
||||
|
||||
// DelegateDel calls the given delegate plugin with the CNI DEL action and
|
||||
// JSON configuration
|
||||
func DelegateDel(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
|
||||
pluginPath, realExec, err := delegateCommon("DEL", delegatePlugin, exec)
|
||||
pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, ArgsFromEnv(), realExec)
|
||||
// DelegateDel will override the original CNI_COMMAND env from process with DEL
|
||||
return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("DEL"), realExec)
|
||||
}
|
||||
|
||||
// return CNIArgs used by delegation
|
||||
func delegateArgs(action string) *DelegateArgs {
|
||||
return &DelegateArgs{
|
||||
Command: action,
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
4
vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go
generated
vendored
@ -46,7 +46,9 @@ func (e *RawExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [
|
||||
func pluginErr(err error, output []byte) error {
|
||||
if _, ok := err.(*exec.ExitError); ok {
|
||||
emsg := types.Error{}
|
||||
if perr := json.Unmarshal(output, &emsg); perr != nil {
|
||||
if len(output) == 0 {
|
||||
emsg.Msg = "netplugin failed with no error message"
|
||||
} else if perr := json.Unmarshal(output, &emsg); perr != nil {
|
||||
emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr)
|
||||
}
|
||||
return &emsg
|
||||
|
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":
|
||||
*b = false
|
||||
default:
|
||||
return fmt.Errorf("Boolean unmarshal error: invalid input %s", s)
|
||||
return fmt.Errorf("boolean unmarshal error: invalid input %s", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
25
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
25
vendor/github.com/containernetworking/cni/pkg/types/types.go
generated
vendored
@ -16,7 +16,6 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@ -134,9 +133,16 @@ func (r *Route) String() string {
|
||||
// Well known error codes
|
||||
// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
|
||||
const (
|
||||
ErrUnknown uint = iota // 0
|
||||
ErrIncompatibleCNIVersion // 1
|
||||
ErrUnsupportedField // 2
|
||||
ErrUnknown uint = iota // 0
|
||||
ErrIncompatibleCNIVersion // 1
|
||||
ErrUnsupportedField // 2
|
||||
ErrUnknownContainer // 3
|
||||
ErrInvalidEnvironmentVariables // 4
|
||||
ErrIOFailure // 5
|
||||
ErrDecodingFailure // 6
|
||||
ErrInvalidNetworkConfig // 7
|
||||
ErrTryAgainLater uint = 11
|
||||
ErrInternal uint = 999
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
@ -145,6 +151,14 @@ type Error struct {
|
||||
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 {
|
||||
details := ""
|
||||
if e.Details != "" {
|
||||
@ -194,6 +208,3 @@ func prettyPrint(obj interface{}) error {
|
||||
_, err = os.Stdout.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// NotImplementedError is used to indicate that a method is not implemented for the given platform
|
||||
var NotImplementedError = errors.New("Not Implemented")
|
||||
|
51
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
51
vendor/github.com/containernetworking/cni/pkg/utils/utils.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// 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 (
|
||||
"regexp"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
)
|
||||
|
||||
// cniValidNameChars is the regexp used to validate valid characters in
|
||||
// containerID and networkName
|
||||
const cniValidNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.\-]`
|
||||
|
||||
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
|
||||
}
|
11
vendor/github.com/cri-o/ocicni/go.mod
generated
vendored
Normal file
11
vendor/github.com/cri-o/ocicni/go.mod
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
module github.com/cri-o/ocicni
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/containernetworking/cni v0.7.2-0.20190725021623-1318d7c94c41
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/onsi/ginkgo v1.8.0
|
||||
github.com/onsi/gomega v1.5.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
)
|
540
vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
generated
vendored
540
vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go
generated
vendored
@ -2,11 +2,14 @@ package ocicni
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -21,10 +24,11 @@ import (
|
||||
)
|
||||
|
||||
type cniNetworkPlugin struct {
|
||||
cniConfig *libcni.CNIConfig
|
||||
loNetwork *cniNetwork
|
||||
|
||||
sync.RWMutex
|
||||
defaultNetName string
|
||||
defaultNetName netName
|
||||
networks map[string]*cniNetwork
|
||||
|
||||
nsManager *nsManager
|
||||
@ -47,11 +51,15 @@ type cniNetworkPlugin struct {
|
||||
cacheDir string
|
||||
}
|
||||
|
||||
type netName struct {
|
||||
name string
|
||||
changeable bool
|
||||
}
|
||||
|
||||
type cniNetwork struct {
|
||||
name string
|
||||
filePath string
|
||||
NetworkConfig *libcni.NetworkConfigList
|
||||
CNIConfig *libcni.CNIConfig
|
||||
name string
|
||||
filePath string
|
||||
config *libcni.NetworkConfigList
|
||||
}
|
||||
|
||||
var errMissingDefaultNetwork = errors.New("Missing CNI default network")
|
||||
@ -186,6 +194,8 @@ func (plugin *cniNetworkPlugin) monitorConfDir(start *sync.WaitGroup) {
|
||||
// If defaultNetName is not empty, a CNI config with that network name will
|
||||
// be used as the default CNI network, and container network operations will
|
||||
// fail until that network config is present and valid.
|
||||
// If defaultNetName is empty, CNI config files should be reloaded real-time and
|
||||
// defaultNetName should be changeable and determined by file sorting.
|
||||
func InitCNI(defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) {
|
||||
return initCNI(nil, "", defaultNetName, confDir, binDirs...)
|
||||
}
|
||||
@ -198,17 +208,24 @@ func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir strin
|
||||
if len(binDirs) == 0 {
|
||||
binDirs = []string{DefaultBinDir}
|
||||
}
|
||||
|
||||
plugin := &cniNetworkPlugin{
|
||||
defaultNetName: defaultNetName,
|
||||
networks: make(map[string]*cniNetwork),
|
||||
loNetwork: getLoNetwork(exec, binDirs),
|
||||
confDir: confDir,
|
||||
binDirs: binDirs,
|
||||
shutdownChan: make(chan struct{}),
|
||||
done: &sync.WaitGroup{},
|
||||
pods: make(map[string]*podLock),
|
||||
exec: exec,
|
||||
cacheDir: cacheDir,
|
||||
cniConfig: libcni.NewCNIConfig(binDirs, exec),
|
||||
defaultNetName: netName{
|
||||
name: defaultNetName,
|
||||
// If defaultNetName is not assigned in initialization,
|
||||
// it should be changeable
|
||||
changeable: defaultNetName == "",
|
||||
},
|
||||
networks: make(map[string]*cniNetwork),
|
||||
loNetwork: getLoNetwork(),
|
||||
confDir: confDir,
|
||||
binDirs: binDirs,
|
||||
shutdownChan: make(chan struct{}),
|
||||
done: &sync.WaitGroup{},
|
||||
pods: make(map[string]*podLock),
|
||||
exec: exec,
|
||||
cacheDir: cacheDir,
|
||||
}
|
||||
|
||||
if exec == nil {
|
||||
@ -246,7 +263,7 @@ func (plugin *cniNetworkPlugin) Shutdown() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[string]*cniNetwork, string, error) {
|
||||
func loadNetworks(confDir string, cni *libcni.CNIConfig) (map[string]*cniNetwork, string, error) {
|
||||
files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"})
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
@ -284,17 +301,30 @@ func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[st
|
||||
logrus.Warningf("CNI config list %s has no networks, skipping", confFile)
|
||||
continue
|
||||
}
|
||||
|
||||
// Validation on CNI config should be done to pre-check presence
|
||||
// of plugins which are necessary.
|
||||
if _, err := cni.ValidateNetworkList(context.TODO(), confList); err != nil {
|
||||
logrus.Warningf("Error validating CNI config file %s: %v", confFile, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if confList.Name == "" {
|
||||
confList.Name = path.Base(confFile)
|
||||
}
|
||||
|
||||
cniNet := &cniNetwork{
|
||||
name: confList.Name,
|
||||
filePath: confFile,
|
||||
config: confList,
|
||||
}
|
||||
|
||||
logrus.Infof("Found CNI network %s (type=%v) at %s", confList.Name, confList.Plugins[0].Network.Type, confFile)
|
||||
|
||||
networks[confList.Name] = &cniNetwork{
|
||||
name: confList.Name,
|
||||
filePath: confFile,
|
||||
NetworkConfig: confList,
|
||||
CNIConfig: libcni.NewCNIConfig(binDirs, exec),
|
||||
if _, ok := networks[confList.Name]; !ok {
|
||||
networks[confList.Name] = cniNet
|
||||
} else {
|
||||
logrus.Infof("Ignore CNI network %s (type=%v) at %s because already exists", confList.Name, confList.Plugins[0].Network.Type, confFile)
|
||||
}
|
||||
|
||||
if defaultNetName == "" {
|
||||
@ -305,39 +335,49 @@ func loadNetworks(exec cniinvoke.Exec, confDir string, binDirs []string) (map[st
|
||||
return networks, defaultNetName, nil
|
||||
}
|
||||
|
||||
func getLoNetwork(exec cniinvoke.Exec, binDirs []string) *cniNetwork {
|
||||
loConfig, err := libcni.ConfListFromBytes([]byte(`{
|
||||
"cniVersion": "0.2.0",
|
||||
"name": "cni-loopback",
|
||||
const (
|
||||
loIfname string = "lo"
|
||||
loNetname string = "cni-loopback"
|
||||
)
|
||||
|
||||
func getLoNetwork() *cniNetwork {
|
||||
loConfig, err := libcni.ConfListFromBytes([]byte(fmt.Sprintf(`{
|
||||
"cniVersion": "0.3.1",
|
||||
"name": "%s",
|
||||
"plugins": [{
|
||||
"type": "loopback"
|
||||
}]
|
||||
}`))
|
||||
}`, loNetname)))
|
||||
if err != nil {
|
||||
// The hardcoded config above should always be valid and unit tests will
|
||||
// catch this
|
||||
panic(err)
|
||||
}
|
||||
loNetwork := &cniNetwork{
|
||||
name: "lo",
|
||||
NetworkConfig: loConfig,
|
||||
CNIConfig: libcni.NewCNIConfig(binDirs, exec),
|
||||
name: loIfname,
|
||||
config: loConfig,
|
||||
}
|
||||
|
||||
return loNetwork
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) syncNetworkConfig() error {
|
||||
networks, defaultNetName, err := loadNetworks(plugin.exec, plugin.confDir, plugin.binDirs)
|
||||
networks, defaultNetName, err := loadNetworks(plugin.confDir, plugin.cniConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plugin.Lock()
|
||||
defer plugin.Unlock()
|
||||
if plugin.defaultNetName == "" {
|
||||
plugin.defaultNetName = defaultNetName
|
||||
|
||||
// Update defaultNetName if it is changeable
|
||||
if plugin.defaultNetName.changeable {
|
||||
plugin.defaultNetName.name = defaultNetName
|
||||
logrus.Infof("Update default CNI network name to %s", defaultNetName)
|
||||
} else {
|
||||
logrus.Warnf("Default CNI network name %s is unchangeable", plugin.defaultNetName.name)
|
||||
}
|
||||
|
||||
plugin.networks = networks
|
||||
|
||||
return nil
|
||||
@ -356,7 +396,7 @@ func (plugin *cniNetworkPlugin) getNetwork(name string) (*cniNetwork, error) {
|
||||
func (plugin *cniNetworkPlugin) GetDefaultNetworkName() string {
|
||||
plugin.RLock()
|
||||
defer plugin.RUnlock()
|
||||
return plugin.defaultNetName
|
||||
return plugin.defaultNetName.name
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork {
|
||||
@ -382,27 +422,120 @@ func (plugin *cniNetworkPlugin) Name() string {
|
||||
return CNIPluginName
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, forEachFunc func(*cniNetwork, string, *PodNetwork) error) error {
|
||||
func (plugin *cniNetworkPlugin) loadNetworkFromCache(name string, rt *libcni.RuntimeConf) (*cniNetwork, *libcni.RuntimeConf, error) {
|
||||
cniNet := &cniNetwork{
|
||||
name: name,
|
||||
config: &libcni.NetworkConfigList{
|
||||
Name: name,
|
||||
},
|
||||
}
|
||||
|
||||
var confBytes []byte
|
||||
var err error
|
||||
confBytes, rt, err = plugin.cniConfig.GetNetworkListCachedConfig(cniNet.config, rt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
} else if confBytes == nil {
|
||||
return nil, nil, fmt.Errorf("network %q not found in CNI cache", name)
|
||||
}
|
||||
|
||||
cniNet.config, err = libcni.ConfListFromBytes(confBytes)
|
||||
if err != nil {
|
||||
// Might be a plain NetworkConfig
|
||||
netConf, err := libcni.ConfFromBytes(confBytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Up-convert to a NetworkConfigList
|
||||
cniNet.config, err = libcni.ConfListFromConf(netConf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return cniNet, rt, nil
|
||||
}
|
||||
|
||||
type forEachNetworkFn func(*cniNetwork, *PodNetwork, *libcni.RuntimeConf) error
|
||||
|
||||
func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, fromCache bool, actionFn forEachNetworkFn) error {
|
||||
networks := podNetwork.Networks
|
||||
if len(networks) == 0 {
|
||||
networks = append(networks, plugin.GetDefaultNetworkName())
|
||||
networks = append(networks, NetAttachment{
|
||||
Name: plugin.GetDefaultNetworkName(),
|
||||
})
|
||||
}
|
||||
for i, netName := range networks {
|
||||
// Interface names start at "eth0" and count up for each network
|
||||
ifName := fmt.Sprintf("eth%d", i)
|
||||
network, err := plugin.getNetwork(netName)
|
||||
|
||||
allIfNames := make(map[string]bool)
|
||||
for _, req := range networks {
|
||||
if req.Ifname != "" {
|
||||
// Make sure the requested name isn't already assigned
|
||||
if allIfNames[req.Ifname] {
|
||||
return fmt.Errorf("network %q requested interface name %q already assigned", req.Name, req.Ifname)
|
||||
}
|
||||
allIfNames[req.Ifname] = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, network := range networks {
|
||||
ifName := network.Ifname
|
||||
if ifName == "" {
|
||||
for i := 0; i < 10000; i++ {
|
||||
candidate := fmt.Sprintf("eth%d", i)
|
||||
if !allIfNames[candidate] {
|
||||
allIfNames[candidate] = true
|
||||
ifName = candidate
|
||||
break
|
||||
}
|
||||
}
|
||||
if ifName == "" {
|
||||
return fmt.Errorf("failed to find free interface name for network %q", network.Name)
|
||||
}
|
||||
}
|
||||
|
||||
rt, err := buildCNIRuntimeConf(plugin.cacheDir, podNetwork, ifName, podNetwork.RuntimeConfig[network.Name])
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
logrus.Errorf("error building CNI runtime config: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := forEachFunc(network, ifName, podNetwork); err != nil {
|
||||
|
||||
var cniNet *cniNetwork
|
||||
if fromCache {
|
||||
var newRt *libcni.RuntimeConf
|
||||
cniNet, newRt, err = plugin.loadNetworkFromCache(network.Name, rt)
|
||||
if err != nil {
|
||||
logrus.Errorf("error loading cached network config: %v", err)
|
||||
// fall back to loading from existing plugins on disk
|
||||
} else {
|
||||
// Use the updated RuntimeConf
|
||||
rt = newRt
|
||||
}
|
||||
}
|
||||
if cniNet == nil {
|
||||
cniNet, err = plugin.getNetwork(network.Name)
|
||||
if err != nil {
|
||||
logrus.Errorf(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := actionFn(cniNet, podNetwork, rt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Result, error) {
|
||||
func buildLoopbackRuntimeConf(cacheDir string, podNetwork *PodNetwork) *libcni.RuntimeConf {
|
||||
return &libcni.RuntimeConf{
|
||||
ContainerID: podNetwork.ID,
|
||||
NetNS: podNetwork.NetNS,
|
||||
CacheDir: cacheDir,
|
||||
IfName: loIfname,
|
||||
}
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, error) {
|
||||
if err := plugin.networksAvailable(&podNetwork); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -410,89 +543,24 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]cnitypes.Resu
|
||||
plugin.podLock(podNetwork).Lock()
|
||||
defer plugin.podUnlock(podNetwork)
|
||||
|
||||
_, err := plugin.loNetwork.addToNetwork(plugin.cacheDir, &podNetwork, "lo", "")
|
||||
if err != nil {
|
||||
loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork)
|
||||
if _, err := plugin.loNetwork.addToNetwork(loRt, plugin.cniConfig); err != nil {
|
||||
logrus.Errorf("Error while adding to cni lo network: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := make([]cnitypes.Result, 0)
|
||||
if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
|
||||
ip := ""
|
||||
if conf, ok := podNetwork.NetworkConfig[network.name]; ok {
|
||||
ip = conf.IP
|
||||
}
|
||||
|
||||
result, err := network.addToNetwork(plugin.cacheDir, podNetwork, ifName, ip)
|
||||
results := make([]NetResult, 0)
|
||||
if err := plugin.forEachNetwork(&podNetwork, false, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
|
||||
result, err := network.addToNetwork(rt, plugin.cniConfig)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err)
|
||||
return err
|
||||
}
|
||||
results = append(results, result)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error {
|
||||
if err := plugin.networksAvailable(&podNetwork); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plugin.podLock(podNetwork).Lock()
|
||||
defer plugin.podUnlock(podNetwork)
|
||||
|
||||
return plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
|
||||
ip := ""
|
||||
if conf, ok := podNetwork.NetworkConfig[network.name]; ok {
|
||||
ip = conf.IP
|
||||
}
|
||||
|
||||
if err := network.deleteFromNetwork(plugin.cacheDir, podNetwork, ifName, ip); err != nil {
|
||||
logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetPodNetworkStatus returns IP addressing and interface details for all
|
||||
// networks attached to the pod.
|
||||
func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cnitypes.Result, error) {
|
||||
plugin.podLock(podNetwork).Lock()
|
||||
defer plugin.podUnlock(podNetwork)
|
||||
|
||||
results := make([]cnitypes.Result, 0)
|
||||
if err := plugin.forEachNetwork(&podNetwork, func(network *cniNetwork, ifName string, podNetwork *PodNetwork) error {
|
||||
version := "4"
|
||||
ip, mac, err := getContainerDetails(plugin.nsManager, podNetwork.NetNS, ifName, "-4")
|
||||
if err != nil {
|
||||
ip, mac, err = getContainerDetails(plugin.nsManager, podNetwork.NetNS, ifName, "-6")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
version = "6"
|
||||
}
|
||||
|
||||
// Until CNI's GET request lands, construct the Result manually
|
||||
results = append(results, &cnicurrent.Result{
|
||||
CNIVersion: "0.3.1",
|
||||
Interfaces: []*cnicurrent.Interface{
|
||||
{
|
||||
Name: ifName,
|
||||
Mac: mac.String(),
|
||||
Sandbox: podNetwork.NetNS,
|
||||
},
|
||||
},
|
||||
IPs: []*cnicurrent.IPConfig{
|
||||
{
|
||||
Version: version,
|
||||
Interface: cnicurrent.Int(0),
|
||||
Address: *ip,
|
||||
},
|
||||
results = append(results, NetResult{
|
||||
Result: result,
|
||||
NetAttachment: NetAttachment{
|
||||
Name: network.name,
|
||||
Ifname: rt.IfName,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
@ -503,16 +571,139 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]cn
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork, ifName, ip string) (cnitypes.Result, error) {
|
||||
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, ip)
|
||||
func (plugin *cniNetworkPlugin) getCachedNetworkInfo(containerID string) ([]NetAttachment, error) {
|
||||
cacheDir := libcni.CacheDir
|
||||
if plugin.cacheDir != "" {
|
||||
cacheDir = plugin.cacheDir
|
||||
}
|
||||
|
||||
dirPath := filepath.Join(cacheDir, "results")
|
||||
entries, err := ioutil.ReadDir(dirPath)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error adding network: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
netconf, cninet := network.NetworkConfig, network.CNIConfig
|
||||
logrus.Infof("About to add CNI network %s (type=%v)", netconf.Name, netconf.Plugins[0].Network.Type)
|
||||
res, err := cninet.AddNetworkList(context.Background(), netconf, rt)
|
||||
fileNames := make([]string, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
fileNames = append(fileNames, e.Name())
|
||||
}
|
||||
sort.Strings(fileNames)
|
||||
|
||||
attachments := []NetAttachment{}
|
||||
for _, fname := range fileNames {
|
||||
part := fmt.Sprintf("-%s-", containerID)
|
||||
pos := strings.Index(fname, part)
|
||||
if pos <= 0 || pos+len(part) >= len(fname) {
|
||||
continue
|
||||
}
|
||||
|
||||
cacheFile := filepath.Join(dirPath, fname)
|
||||
bytes, err := ioutil.ReadFile(cacheFile)
|
||||
if err != nil {
|
||||
logrus.Warningf("failed to read CNI cache file %s: %v", cacheFile, err)
|
||||
continue
|
||||
}
|
||||
|
||||
cachedInfo := struct {
|
||||
Kind string `json:"kind"`
|
||||
IfName string `json:"ifName"`
|
||||
ContainerID string `json:"containerID"`
|
||||
NetName string `json:"networkName"`
|
||||
}{}
|
||||
|
||||
if err := json.Unmarshal(bytes, &cachedInfo); err != nil {
|
||||
logrus.Warningf("failed to unmarshal CNI cache file %s: %v", cacheFile, err)
|
||||
continue
|
||||
}
|
||||
if cachedInfo.Kind != libcni.CNICacheV1 {
|
||||
logrus.Warningf("unknown CNI cache file %s kind %q", cacheFile, cachedInfo.Kind)
|
||||
continue
|
||||
}
|
||||
if cachedInfo.ContainerID != containerID {
|
||||
continue
|
||||
}
|
||||
// Ignore the loopback interface; it's handled separately
|
||||
if cachedInfo.IfName == loIfname && cachedInfo.NetName == loNetname {
|
||||
continue
|
||||
}
|
||||
if cachedInfo.IfName == "" || cachedInfo.NetName == "" {
|
||||
logrus.Warningf("missing CNI cache file %s ifname %q or netname %q", cacheFile, cachedInfo.IfName, cachedInfo.NetName)
|
||||
continue
|
||||
}
|
||||
|
||||
attachments = append(attachments, NetAttachment{
|
||||
Name: cachedInfo.NetName,
|
||||
Ifname: cachedInfo.IfName,
|
||||
})
|
||||
}
|
||||
return attachments, nil
|
||||
}
|
||||
|
||||
// TearDownPod tears down pod networks. Prefers cached pod attachment information
|
||||
// but falls back to given network attachment information.
|
||||
func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error {
|
||||
if len(podNetwork.Networks) == 0 {
|
||||
attachments, err := plugin.getCachedNetworkInfo(podNetwork.ID)
|
||||
if err == nil && len(attachments) > 0 {
|
||||
podNetwork.Networks = attachments
|
||||
}
|
||||
}
|
||||
|
||||
if err := plugin.networksAvailable(&podNetwork); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork)
|
||||
if err := plugin.loNetwork.deleteFromNetwork(loRt, plugin.cniConfig); err != nil {
|
||||
logrus.Errorf("Error while removing pod from CNI lo network: %v", err)
|
||||
// Loopback teardown errors are not fatal
|
||||
}
|
||||
|
||||
plugin.podLock(podNetwork).Lock()
|
||||
defer plugin.podUnlock(podNetwork)
|
||||
|
||||
return plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
|
||||
if err := network.deleteFromNetwork(rt, plugin.cniConfig); err != nil {
|
||||
logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetPodNetworkStatus returns IP addressing and interface details for all
|
||||
// networks attached to the pod.
|
||||
func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]NetResult, error) {
|
||||
plugin.podLock(podNetwork).Lock()
|
||||
defer plugin.podUnlock(podNetwork)
|
||||
|
||||
results := make([]NetResult, 0)
|
||||
if err := plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error {
|
||||
result, err := network.checkNetwork(rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error while checking pod to CNI network %q: %s", network.name, err)
|
||||
return err
|
||||
}
|
||||
if result != nil {
|
||||
results = append(results, NetResult{
|
||||
Result: result,
|
||||
NetAttachment: NetAttachment{
|
||||
Name: network.name,
|
||||
Ifname: rt.IfName,
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (network *cniNetwork) addToNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) {
|
||||
logrus.Infof("About to add CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
|
||||
res, err := cni.AddNetworkList(context.Background(), network.config, rt)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error adding network: %v", err)
|
||||
return nil, err
|
||||
@ -521,24 +712,88 @@ func (network *cniNetwork) addToNetwork(cacheDir string, podNetwork *PodNetwork,
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (network *cniNetwork) deleteFromNetwork(cacheDir string, podNetwork *PodNetwork, ifName, ip string) error {
|
||||
rt, err := buildCNIRuntimeConf(cacheDir, podNetwork, ifName, ip)
|
||||
func (network *cniNetwork) checkNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) {
|
||||
logrus.Infof("About to check CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
|
||||
|
||||
gtet, err := cniversion.GreaterThanOrEqualTo(network.config.CNIVersion, "0.4.0")
|
||||
if err != nil {
|
||||
logrus.Errorf("Error deleting network: %v", err)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
netconf, cninet := network.NetworkConfig, network.CNIConfig
|
||||
logrus.Infof("About to del CNI network %s (type=%v)", netconf.Name, netconf.Plugins[0].Network.Type)
|
||||
err = cninet.DelNetworkList(context.Background(), netconf, rt)
|
||||
var result cnitypes.Result
|
||||
|
||||
// When CNIVersion supports Check, use it. Otherwise fall back on what was done initially.
|
||||
if gtet {
|
||||
err = cni.CheckNetworkList(context.Background(), network.config, rt)
|
||||
logrus.Infof("Checking CNI network %s (config version=%v)", network.name, network.config.CNIVersion)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error checking network: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
result, err = cni.GetNetworkListCachedResult(network.config, rt)
|
||||
if err != nil {
|
||||
logrus.Errorf("Error GetNetworkListCachedResult: %v", err)
|
||||
return nil, err
|
||||
} else if result != nil {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// result doesn't exist, create one
|
||||
logrus.Infof("Checking CNI network %s (config version=%v) nsManager=%v", network.name, network.config.CNIVersion, nsManager)
|
||||
|
||||
var cniInterface *cnicurrent.Interface
|
||||
ips := []*cnicurrent.IPConfig{}
|
||||
errs := []error{}
|
||||
for _, version := range []string{"4", "6"} {
|
||||
ip, mac, err := getContainerDetails(nsManager, netns, rt.IfName, "-"+version)
|
||||
if err == nil {
|
||||
if cniInterface == nil {
|
||||
cniInterface = &cnicurrent.Interface{
|
||||
Name: rt.IfName,
|
||||
Mac: mac.String(),
|
||||
Sandbox: netns,
|
||||
}
|
||||
}
|
||||
ips = append(ips, &cnicurrent.IPConfig{
|
||||
Version: version,
|
||||
Interface: cnicurrent.Int(0),
|
||||
Address: *ip,
|
||||
})
|
||||
} else {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if cniInterface == nil || len(ips) == 0 {
|
||||
return nil, fmt.Errorf("neither IPv4 nor IPv6 found when retrieving network status: %v", errs)
|
||||
}
|
||||
|
||||
result = &cnicurrent.Result{
|
||||
CNIVersion: network.config.CNIVersion,
|
||||
Interfaces: []*cnicurrent.Interface{cniInterface},
|
||||
IPs: ips,
|
||||
}
|
||||
|
||||
// Result must be the same CNIVersion as the CNI config
|
||||
converted, err := result.GetAsVersion(network.config.CNIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
func (network *cniNetwork) deleteFromNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error {
|
||||
logrus.Infof("About to del CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type)
|
||||
if err := cni.DelNetworkList(context.Background(), network.config, rt); err != nil {
|
||||
logrus.Errorf("Error deleting network: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName, ip string) (*libcni.RuntimeConf, error) {
|
||||
func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig) (*libcni.RuntimeConf, error) {
|
||||
logrus.Infof("Got pod network %+v", podNetwork)
|
||||
|
||||
rt := &libcni.RuntimeConf{
|
||||
@ -552,9 +807,11 @@ func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName, ip str
|
||||
{"K8S_POD_NAME", podNetwork.Name},
|
||||
{"K8S_POD_INFRA_CONTAINER_ID", podNetwork.ID},
|
||||
},
|
||||
CapabilityArgs: map[string]interface{}{},
|
||||
}
|
||||
|
||||
// Add requested static IP to CNI_ARGS
|
||||
ip := runtimeConfig.IP
|
||||
if ip != "" {
|
||||
if tstIP := net.ParseIP(ip); tstIP == nil {
|
||||
return nil, fmt.Errorf("unable to parse IP address %q", ip)
|
||||
@ -562,13 +819,26 @@ func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName, ip str
|
||||
rt.Args = append(rt.Args, [2]string{"IP", ip})
|
||||
}
|
||||
|
||||
if len(podNetwork.PortMappings) == 0 {
|
||||
return rt, nil
|
||||
// Set PortMappings in Capabilities
|
||||
if len(runtimeConfig.PortMappings) != 0 {
|
||||
rt.CapabilityArgs["portMappings"] = runtimeConfig.PortMappings
|
||||
}
|
||||
|
||||
rt.CapabilityArgs = map[string]interface{}{
|
||||
"portMappings": podNetwork.PortMappings,
|
||||
// Set Bandwidth in Capabilities
|
||||
if runtimeConfig.Bandwidth != nil {
|
||||
rt.CapabilityArgs["bandwidth"] = map[string]uint64{
|
||||
"ingressRate": runtimeConfig.Bandwidth.IngressRate,
|
||||
"ingressBurst": runtimeConfig.Bandwidth.IngressBurst,
|
||||
"egressRate": runtimeConfig.Bandwidth.EgressRate,
|
||||
"egressBurst": runtimeConfig.Bandwidth.EgressBurst,
|
||||
}
|
||||
}
|
||||
|
||||
// Set IpRanges in Capabilities
|
||||
if len(runtimeConfig.IpRanges) > 0 {
|
||||
rt.CapabilityArgs["ipRanges"] = runtimeConfig.IpRanges
|
||||
}
|
||||
|
||||
return rt, nil
|
||||
}
|
||||
|
||||
|
69
vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go
generated
vendored
69
vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go
generated
vendored
@ -24,12 +24,44 @@ type PortMapping struct {
|
||||
HostIP string `json:"hostIP"`
|
||||
}
|
||||
|
||||
// NetworkConfig is additional configuration for a single CNI network.
|
||||
type NetworkConfig struct {
|
||||
// IpRange maps to the standard CNI ipRanges Capability
|
||||
// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
|
||||
type IpRange struct {
|
||||
// Subnet is the whole CIDR
|
||||
Subnet string `json:"subnet"`
|
||||
// RangeStart is the first available IP in subnet
|
||||
RangeStart string `json:"rangeStart,omitempty"`
|
||||
// RangeEnd is the last available IP in subnet
|
||||
RangeEnd string `json:"rangeEnd,omitempty"`
|
||||
// Gateway is the gateway of subnet
|
||||
Gateway string `json:"gateway,omitempty"`
|
||||
}
|
||||
|
||||
// RuntimeConfig is additional configuration for a single CNI network that
|
||||
// is pod-specific rather than general to the network.
|
||||
type RuntimeConfig struct {
|
||||
// IP is a static IP to be specified in the network. Can only be used
|
||||
// with the hostlocal IP allocator. If left unset, an IP will be
|
||||
// dynamically allocated.
|
||||
IP string
|
||||
// PortMappings is the port mapping of the sandbox.
|
||||
PortMappings []PortMapping
|
||||
// Bandwidth is the bandwidth limiting of the pod
|
||||
Bandwidth *BandwidthConfig
|
||||
// IpRanges is the ip range gather which is used for address allocation
|
||||
IpRanges [][]IpRange
|
||||
}
|
||||
|
||||
// BandwidthConfig maps to the standard CNI bandwidth Capability
|
||||
// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
|
||||
type BandwidthConfig struct {
|
||||
// IngressRate is a limit for incoming traffic in bps
|
||||
IngressRate uint64
|
||||
IngressBurst uint64
|
||||
|
||||
// EgressRate is a limit for outgoing traffic in bps
|
||||
EgressRate uint64
|
||||
EgressBurst uint64
|
||||
}
|
||||
|
||||
// PodNetwork configures the network of a pod sandbox.
|
||||
@ -42,17 +74,34 @@ type PodNetwork struct {
|
||||
ID string
|
||||
// NetNS is the network namespace path of the sandbox.
|
||||
NetNS string
|
||||
// PortMappings is the port mapping of the sandbox.
|
||||
PortMappings []PortMapping
|
||||
|
||||
// Networks is a list of CNI network names to attach to the sandbox
|
||||
// Leave this list empty to attach the default network to the sandbox
|
||||
Networks []string
|
||||
// Networks is a list of CNI network names (and optional interface
|
||||
// names) to attach to the sandbox. Leave this list empty to attach the
|
||||
// default network to the sandbox
|
||||
Networks []NetAttachment
|
||||
|
||||
// NetworkConfig is configuration specific to a single CNI network.
|
||||
// It is optional, and can be omitted for some or all specified networks
|
||||
// without issue.
|
||||
NetworkConfig map[string]NetworkConfig
|
||||
RuntimeConfig map[string]RuntimeConfig
|
||||
}
|
||||
|
||||
// NetAttachment describes a container network attachment
|
||||
type NetAttachment struct {
|
||||
// NetName contains the name of the CNI network to which the container
|
||||
// should be or is attached
|
||||
Name string
|
||||
// Ifname contains the optional interface name of the attachment
|
||||
Ifname string
|
||||
}
|
||||
|
||||
// NetResult contains the result the network attachment operation
|
||||
type NetResult struct {
|
||||
// Result is the CNI Result
|
||||
Result types.Result
|
||||
// NetAttachment contains the network and interface names of this
|
||||
// network attachment
|
||||
NetAttachment
|
||||
}
|
||||
|
||||
// CNIPlugin is the interface that needs to be implemented by a plugin
|
||||
@ -68,13 +117,13 @@ type CNIPlugin interface {
|
||||
// SetUpPod is the method called after the sandbox container of
|
||||
// the pod has been created but before the other containers of the
|
||||
// pod are launched.
|
||||
SetUpPod(network PodNetwork) ([]types.Result, error)
|
||||
SetUpPod(network PodNetwork) ([]NetResult, error)
|
||||
|
||||
// TearDownPod is the method called before a pod's sandbox container will be deleted
|
||||
TearDownPod(network PodNetwork) error
|
||||
|
||||
// Status is the method called to obtain the ipv4 or ipv6 addresses of the pod sandbox
|
||||
GetPodNetworkStatus(network PodNetwork) ([]types.Result, error)
|
||||
GetPodNetworkStatus(network PodNetwork) ([]NetResult, error)
|
||||
|
||||
// NetworkStatus returns error if the network plugin is in error state
|
||||
Status() error
|
||||
|
13
vendor/github.com/cri-o/ocicni/vendor.conf
generated
vendored
13
vendor/github.com/cri-o/ocicni/vendor.conf
generated
vendored
@ -1,13 +0,0 @@
|
||||
github.com/containernetworking/cni fbb95fff8a5239a4295c991efa8a397d43118f7e
|
||||
github.com/fsnotify/fsnotify 1485a34d5d5723fea214f5710708e19a831720e4
|
||||
github.com/sirupsen/logrus 787e519fa85519b874dead61020de598e9a23944
|
||||
github.com/onsi/ginkgo eea6ad008b96acdaa524f5b409513bf062b500ad
|
||||
github.com/onsi/gomega 90e289841c1ed79b7a598a7cd9959750cb5e89e2
|
||||
golang.org/x/net 63eda1eb0650888965ead1296efd04d0b2b61128
|
||||
gopkg.in/yaml.v2 51d6538a90f86fe93ac480b35f37b2be17fef232
|
||||
golang.org/x/text e3703dcdd614d2d7488fff034c75c551ea25da95
|
||||
golang.org/x/sys f49334f85ddcf0f08d7fb6dd7363e9e6d6b777eb
|
||||
github.com/hpcloud/tail a1dbeea552b7c8df4b542c66073e393de198a800
|
||||
gopkg.in/tomb.v1 dd632973f1e7218eb1089048e0798ec9ae7dceb8
|
||||
gopkg.in/fsnotify/fsnotify.v1 c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9
|
||||
github.com/konsorten/go-windows-terminal-sequences f55edac94c9bbba5d6182a4be46d86a2c9b5b50e
|
Reference in New Issue
Block a user