Update cri to ac043660063cf4fd93aa17aeb8bfcaf2d7d249ab.

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu committed 2018-10-29 17:50:02 -07:00
1 parent 9f2e07b1fc
commit 004e97846d
12 files changed
+170 -143

No files matched your search

+2 -2
View File
@@ -44,8 +44,8 @@ github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010
github.com/google/go-cmp v0.1.0
# cri dependencies
github.com/containerd/cri f117382467baf182382c44332bfbf488effc34bb # release/1.0
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
github.com/containerd/cri ac043660063cf4fd93aa17aeb8bfcaf2d7d249ab # release/1.0
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0
github.com/containernetworking/plugins v0.7.0
+3 -2
View File
@@ -99,7 +99,8 @@ func toCRIContainerStatus(container containerstore.Container, spec *runtime.Imag
}
}
type containerInfo struct {
// ContainerInfo is extra information for a container.
type ContainerInfo struct {
// TODO(random-liu): Add sandboxID in CRI container status.
SandboxID string `json:"sandboxID"`
Pid uint32 `json:"pid"`
@@ -122,7 +123,7 @@ func toCRIContainerInfo(ctx context.Context, container containerstore.Container,
status := container.Status.Get()
// TODO(random-liu): Change CRI status info to use array instead of map.
ci := &containerInfo{
ci := &ContainerInfo{
SandboxID: container.SandboxID,
Pid: status.Pid,
Removing: status.Removing,
+3 -2
View File
@@ -100,8 +100,9 @@ func toCRISandboxStatus(meta sandboxstore.Metadata, status sandboxstore.Status,
}
}
// SandboxInfo is extra information for sandbox.
// TODO (mikebrow): discuss predefining constants structures for some or all of these field names in CRI
type sandboxInfo struct {
type SandboxInfo struct {
Pid uint32 `json:"pid"`
Status string `json:"processStatus"`
NetNSClosed bool `json:"netNamespaceClosed"`
@@ -131,7 +132,7 @@ func toCRISandboxInfo(ctx context.Context, sandbox sandboxstore.Sandbox) (map[st
processStatus = taskStatus.Status
}
si := &sandboxInfo{
si := &SandboxInfo{
Pid: sandbox.Status.Get().Pid,
Status: string(processStatus),
Config: sandbox.Config,
+14 -17
View File
@@ -17,7 +17,6 @@ limitations under the License.
package server
import (
"os"
"time"
"github.com/containerd/containerd"
@@ -60,23 +59,21 @@ func (c *criService) StopPodSandbox(ctx context.Context, r *runtime.StopPodSandb
}
// Teardown network for sandbox.
if sandbox.NetNSPath != "" && sandbox.NetNS != nil {
if _, err := os.Stat(sandbox.NetNSPath); err != nil {
if !os.IsNotExist(err) {
return nil, errors.Wrapf(err, "failed to stat network namespace path %s", sandbox.NetNSPath)
}
} else {
if teardownErr := c.teardownPod(id, sandbox.NetNSPath, sandbox.Config); teardownErr != nil {
return nil, errors.Wrapf(teardownErr, "failed to destroy network for sandbox %q", id)
}
if sandbox.NetNSPath != "" {
netNSPath := sandbox.NetNSPath
if sandbox.NetNS == nil || sandbox.NetNS.Closed() {
// Use empty netns path if netns is not available. This is defined in:
// https://github.com/containernetworking/cni/blob/v0.7.0-alpha1/SPEC.md
netNSPath = ""
}
/*TODO:It is still possible that containerd crashes after we teardown the network, but before we remove the network namespace.
In that case, we'll not be able to remove the sandbox anymore. The chance is slim, but we should be aware of that.
In the future, once TearDownPod is idempotent, this will be fixed.*/
//Close the sandbox network namespace if it was created
if err = sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
if err := c.teardownPod(id, netNSPath, sandbox.Config); err != nil {
return nil, errors.Wrapf(err, "failed to destroy network for sandbox %q", id)
}
// Close the sandbox network namespace if it was created
if sandbox.NetNS != nil {
if err = sandbox.NetNS.Remove(); err != nil {
return nil, errors.Wrapf(err, "failed to remove network namespace for sandbox %q", id)
}
}
}
+1 -1
View File
@@ -148,7 +148,7 @@ func NewCRIService(config criconfig.Config, client *containerd.Client) (CRIServi
// Try to load the config if it exists. Just log the error if load fails
// This is not disruptive for containerd to panic
if err := c.netPlugin.Load(cni.WithLoNetwork(), cni.WithDefaultConf()); err != nil {
if err := c.netPlugin.Load(cni.WithLoNetwork, cni.WithDefaultConf); err != nil {
logrus.WithError(err).Error("Failed to load cni during init, please check CRI plugin status before setting up network for pods")
}
// prepare streaming server
+1 -1
View File
@@ -44,7 +44,7 @@ func (c *criService) Status(ctx context.Context, r *runtime.StatusRequest) (*run
// Check the status of the cni initialization
if err := c.netPlugin.Status(); err != nil {
// If it is not initialized, then load the config and retry
if err = c.netPlugin.Load(cni.WithLoNetwork(), cni.WithDefaultConf()); err != nil {
if err = c.netPlugin.Load(cni.WithLoNetwork, cni.WithDefaultConf); err != nil {
networkCondition.Status = false
networkCondition.Reason = networkNotReadyReason
networkCondition.Message = fmt.Sprintf("Network plugin returns error: %v", err)
+1 -1
View File
@@ -52,7 +52,7 @@ func (c *criService) UpdateRuntimeConfig(ctx context.Context, r *runtime.UpdateR
if err := c.netPlugin.Status(); err == nil {
logrus.Infof("Network plugin is ready, skip generating cni config from template %q", confTemplate)
return &runtime.UpdateRuntimeConfigResponse{}, nil
} else if err := c.netPlugin.Load(cni.WithLoNetwork(), cni.WithDefaultConf()); err == nil {
} else if err := c.netPlugin.Load(cni.WithLoNetwork, cni.WithDefaultConf); err == nil {
logrus.Infof("CNI config is successfully loaded, skip generating cni config from template %q", confTemplate)
return &runtime.UpdateRuntimeConfigResponse{}, nil
}
+7
View File
@@ -28,6 +28,13 @@ import (
osinterface "github.com/containerd/cri/pkg/os"
)
// The NetNS library assumes only containerd manages the lifecycle of the
// network namespace mount. The only case that netns will be unmounted by
// someone else is node reboot.
// If this assumption is broken, NetNS won't be aware of the external
// unmount, and there will be a state mismatch.
// TODO(random-liu): Don't cache state, always load from the system.
// ErrClosedNetNS is the error returned when network namespace is closed.
var ErrClosedNetNS = errors.New("network namespace is closed")
+1 -1
View File
@@ -7,7 +7,7 @@ github.com/containerd/console 4d8a41f4ce5b9bae77c41786ea2458330f43f081
github.com/containerd/containerd 57508dcb0b5776efaacd0828ed42f819fab5ba07
github.com/containerd/continuity a60600ad77f38aaa70165825f61e2ea72e51c9b1
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
github.com/containerd/go-runc bcb223a061a3dd7de1a89c0b402a60f4dd9bd307
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
github.com/containernetworking/cni v0.6.0
+14 -11
View File
@@ -1,7 +1,10 @@
[![Build Status](https://travis-ci.org/containerd/go-cni.svg?branch=master)](https://travis-ci.org/containerd/go-cni)
# go-cni
A generic CNI library to provide APIs for CNI plugin interactions. The library provides APIs to:
- Load CNI network config from different sources
- Setup networks for container namespace
- Remove networks from container namespace
- Query status of CNI network plugin initialization
@@ -16,11 +19,17 @@ func main() {
defaultIfName := "eth0"
// Initialize library
l = gocni.New(gocni.WithMinNetworkCount(2),
gocni.WithLoNetwork(),
gocni.WithPluginConfDir("/etc/mycni/net.d"),
gocni.WithPluginDir([]string{"/opt/mycni/bin", "/opt/cni/bin"}),
gocni.WithDefaultIfName(defaultIfName))
// Load the cni configuration
err:= l.Load(gocni.WithLoNetwork,gocni.WithDefaultConf)
if err != nil{
log.Errorf("failed to load cni configuration: %v", err)
return
}
// Setup network for namespace.
labels := map[string]string{
"K8S_POD_NAMESPACE": "namespace1",
@@ -29,16 +38,10 @@ func main() {
}
result, err := l.Setup(id, netns, gocni.WithLabels(labels))
if err != nil {
return nil, fmt.Errorf("failed to setup network for namespace %q: %v", id, err)
log.Errorf("failed to setup network for namespace %q: %v",id, err)
return
}
defer func() {
if retErr != nil {
// Teardown network if an error is returned.
if err := l.Remove(id, netns, gocni.WithLabels(labels)); err != nil {
fmt.Errorf("Failed to destroy network for namespace %q", id)
}
}
}()
// Get IP of the default interface
IP := result.Interfaces[defaultIfName].IPConfigs[0].IP.String()
fmt.Printf("IP of the default interface %s:%s", defaultIfName, IP)
+33 -19
View File
@@ -18,6 +18,7 @@ package cni
import (
"fmt"
"strings"
"sync"
cnilibrary "github.com/containernetworking/cni/libcni"
@@ -31,7 +32,7 @@ type CNI interface {
// Remove tears down the network of the namespace.
Remove(id string, path string, opts ...NamespaceOpts) error
// Load loads the cni network config
Load(opts ...LoadOption) error
Load(opts ...CNIOpt) error
// Status checks the status of the cni initialization
Status() error
}
@@ -59,7 +60,7 @@ func defaultCNIConfig() *libcni {
}
}
func New(config ...ConfigOption) (CNI, error) {
func New(config ...CNIOpt) (CNI, error) {
cni := defaultCNIConfig()
var err error
for _, c := range config {
@@ -70,8 +71,10 @@ func New(config ...ConfigOption) (CNI, error) {
return cni, nil
}
func (c *libcni) Load(opts ...LoadOption) error {
func (c *libcni) Load(opts ...CNIOpt) error {
var err error
c.Lock()
defer c.Unlock()
// Reset the networks on a load operation to ensure
// config happens on a clean slate
c.reset()
@@ -81,30 +84,27 @@ func (c *libcni) Load(opts ...LoadOption) error {
return errors.Wrapf(ErrLoad, fmt.Sprintf("cni config load failed: %v", err))
}
}
return c.Status()
return nil
}
func (c *libcni) Status() error {
c.RLock()
defer c.RUnlock()
if len(c.networks) < c.networkCount {
return ErrCNINotInitialized
}
return nil
return c.status()
}
// Setup setups the network in the namespace
func (c *libcni) Setup(id string, path string, opts ...NamespaceOpts) (*CNIResult, error) {
if err:=c.Status();err!=nil{
return nil,err
c.RLock()
defer c.RUnlock()
if err := c.status(); err != nil {
return nil, err
}
ns, err := newNamespace(id, path, opts...)
if err != nil {
return nil, err
}
var results []*current.Result
c.RLock()
defer c.RUnlock()
for _, network := range c.networks {
r, err := network.Attach(ns)
if err != nil {
@@ -117,17 +117,26 @@ func (c *libcni) Setup(id string, path string, opts ...NamespaceOpts) (*CNIResul
// Remove removes the network config from the namespace
func (c *libcni) Remove(id string, path string, opts ...NamespaceOpts) error {
if err:=c.Status();err!=nil{
return err
}
c.RLock()
defer c.RUnlock()
if err := c.status(); err != nil {
return err
}
ns, err := newNamespace(id, path, opts...)
if err != nil {
return err
}
c.RLock()
defer c.RUnlock()
for _, network := range c.networks {
if err := network.Remove(ns); err != nil {
// Based on CNI spec v0.7.0, empty network namespace is allowed to
// do best effort cleanup. However, it is not handled consistently
// right now:
// https://github.com/containernetworking/plugins/issues/210
// TODO(random-liu): Remove the error handling when the issue is
// fixed and the CNI spec v0.6.0 support is deprecated.
if path == "" && strings.Contains(err.Error(), "no such file or directory") {
continue
}
return err
}
}
@@ -135,7 +144,12 @@ func (c *libcni) Remove(id string, path string, opts ...NamespaceOpts) error {
}
func (c *libcni) reset() {
c.Lock()
defer c.Unlock()
c.networks = nil
}
func (c *libcni) status() error {
if len(c.networks) < c.networkCount {
return ErrCNINotInitialized
}
return nil
}
+90 -86
View File
@@ -24,11 +24,11 @@ import (
"github.com/pkg/errors"
)
type ConfigOption func(c *libcni) error
type CNIOpt func(c *libcni) error
// WithInterfacePrefix sets the prefix for network interfaces
// e.g. eth or wlan
func WithInterfacePrefix(prefix string) ConfigOption {
func WithInterfacePrefix(prefix string) CNIOpt {
return func(c *libcni) error {
c.prefix = prefix
return nil
@@ -37,7 +37,7 @@ func WithInterfacePrefix(prefix string) ConfigOption {
// WithPluginDir can be used to set the locations of
// the cni plugin binaries
func WithPluginDir(dirs []string) ConfigOption {
func WithPluginDir(dirs []string) CNIOpt {
return func(c *libcni) error {
c.pluginDirs = dirs
c.cniConfig = &cnilibrary.CNIConfig{Path: dirs}
@@ -47,7 +47,7 @@ func WithPluginDir(dirs []string) ConfigOption {
// WithPluginConfDir can be used to configure the
// cni configuration directory.
func WithPluginConfDir(dir string) ConfigOption {
func WithPluginConfDir(dir string) CNIOpt {
return func(c *libcni) error {
c.pluginConfDir = dir
return nil
@@ -57,23 +57,17 @@ func WithPluginConfDir(dir string) ConfigOption {
// WithMinNetworkCount can be used to configure the
// minimum networks to be configured and initalized
// for the status to report success. By default its 1.
func WithMinNetworkCount(count int) ConfigOption {
func WithMinNetworkCount(count int) CNIOpt {
return func(c *libcni) error {
c.networkCount = count
return nil
}
}
// LoadOption can be used with Load API
// to load network configuration from different
// sources.
type LoadOption func(c *libcni) error
// WithLoNetwork can be used to load the loopback
// network config.
func WithLoNetwork() LoadOption {
return func(c *libcni) error {
loConfig, _ := cnilibrary.ConfListFromBytes([]byte(`{
func WithLoNetwork(c *libcni) error {
loConfig, _ := cnilibrary.ConfListFromBytes([]byte(`{
"cniVersion": "0.3.1",
"name": "cni-loopback",
"plugins": [{
@@ -81,20 +75,17 @@ func WithLoNetwork() LoadOption {
}]
}`))
c.Lock()
defer c.Unlock()
c.networks = append(c.networks,&Network{
cni: c.cniConfig,
config: loConfig,
ifName: "lo",
})
return nil
}
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: loConfig,
ifName: "lo",
})
return nil
}
// WithConf can be used to load config directly
// from byte.
func WithConf(bytes []byte) LoadOption {
func WithConf(bytes []byte) CNIOpt {
return func(c *libcni) error {
conf, err := cnilibrary.ConfFromBytes(bytes)
if err != nil {
@@ -104,8 +95,6 @@ func WithConf(bytes []byte) LoadOption {
if err != nil {
return err
}
c.Lock()
defer c.Unlock()
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: confList,
@@ -118,7 +107,7 @@ func WithConf(bytes []byte) LoadOption {
// WithConfFile can be used to load network config
// from an .conf file. Supported with absolute fileName
// with path only.
func WithConfFile(fileName string) LoadOption {
func WithConfFile(fileName string) CNIOpt {
return func(c *libcni) error {
conf, err := cnilibrary.ConfFromFile(fileName)
if err != nil {
@@ -129,8 +118,6 @@ func WithConfFile(fileName string) LoadOption {
if err != nil {
return err
}
c.Lock()
defer c.Unlock()
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: confList,
@@ -143,84 +130,101 @@ func WithConfFile(fileName string) LoadOption {
// WithConfListFile can be used to load network config
// from an .conflist file. Supported with absolute fileName
// with path only.
func WithConfListFile(fileName string) LoadOption {
func WithConfListFile(fileName string) CNIOpt {
return func(c *libcni) error {
confList, err := cnilibrary.ConfListFromFile(fileName)
if err != nil {
return err
}
c.Lock()
defer c.Unlock()
c.networks = append(c.networks,&Network{
i := len(c.networks)
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: confList,
ifName: getIfName(c.prefix, 0),
ifName: getIfName(c.prefix, i),
})
return nil
}
}
// WithDefaultConf can be used to detect network config
// WithDefaultConf can be used to detect the default network
// config file from the configured cni config directory and load
// it.
// Since the CNI spec does not specify a way to detect default networks,
// the convention chosen is - the first network configuration in the sorted
// list of network conf files as the default network.
func WithDefaultConf(c *libcni) error {
return loadFromConfDir(c, 1)
}
// WithAllConf can be used to detect all network config
// files from the configured cni config directory and load
// them.
func WithDefaultConf() LoadOption {
return func(c *libcni) error {
files, err := cnilibrary.ConfFiles(c.pluginConfDir, []string{".conf", ".conflist", ".json"})
switch {
case err != nil:
return errors.Wrapf(ErrRead, "failed to read config file: %v", err)
case len(files) == 0:
return errors.Wrapf(ErrCNINotInitialized, "no network config found in %s", c.pluginConfDir)
}
func WithAllConf(c *libcni) error {
return loadFromConfDir(c, 0)
}
// files contains the network config files associated with cni network.
// Use lexicographical way as a defined order for network config files.
sort.Strings(files)
// Since the CNI spec does not specify a way to detect default networks,
// the convention chosen is - the first network configuration in the sorted
// list of network conf files as the default network and choose the default
// interface provided during init as the network interface for this default
// network. For every other network use a generated interface id.
i := 0
c.Lock()
defer c.Unlock()
for _, confFile := range files {
var confList *cnilibrary.NetworkConfigList
if strings.HasSuffix(confFile, ".conflist") {
confList, err = cnilibrary.ConfListFromFile(confFile)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config list file %s: %v", confFile, err)
}
} else {
conf, err := cnilibrary.ConfFromFile(confFile)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config file %s: %v", confFile, err)
}
// Ensure the config has a "type" so we know what plugin to run.
// Also catches the case where somebody put a conflist into a conf file.
if conf.Network.Type == "" {
return errors.Wrapf(ErrInvalidConfig, "network type not found in %s", confFile)
}
// loadFromConfDir detects network config files from the
// configured cni config directory and load them. max is
// the maximum network config to load (max i<= 0 means no limit).
func loadFromConfDir(c *libcni, max int) error {
files, err := cnilibrary.ConfFiles(c.pluginConfDir, []string{".conf", ".conflist", ".json"})
switch {
case err != nil:
return errors.Wrapf(ErrRead, "failed to read config file: %v", err)
case len(files) == 0:
return errors.Wrapf(ErrCNINotInitialized, "no network config found in %s", c.pluginConfDir)
}
confList, err = cnilibrary.ConfListFromConf(conf)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to convert CNI config file %s to list: %v", confFile, err)
}
// files contains the network config files associated with cni network.
// Use lexicographical way as a defined order for network config files.
sort.Strings(files)
// Since the CNI spec does not specify a way to detect default networks,
// the convention chosen is - the first network configuration in the sorted
// list of network conf files as the default network and choose the default
// interface provided during init as the network interface for this default
// network. For every other network use a generated interface id.
i := 0
var networks []*Network
for _, confFile := range files {
var confList *cnilibrary.NetworkConfigList
if strings.HasSuffix(confFile, ".conflist") {
confList, err = cnilibrary.ConfListFromFile(confFile)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config list file %s: %v", confFile, err)
}
} else {
conf, err := cnilibrary.ConfFromFile(confFile)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to load CNI config file %s: %v", confFile, err)
}
// Ensure the config has a "type" so we know what plugin to run.
// Also catches the case where somebody put a conflist into a conf file.
if conf.Network.Type == "" {
return errors.Wrapf(ErrInvalidConfig, "network type not found in %s", confFile)
}
if len(confList.Plugins) == 0 {
return errors.Wrapf(ErrInvalidConfig, "CNI config list %s has no networks, skipping", confFile)
confList, err = cnilibrary.ConfListFromConf(conf)
if err != nil {
return errors.Wrapf(ErrInvalidConfig, "failed to convert CNI config file %s to list: %v", confFile, err)
}
c.networks = append(c.networks, &Network{
cni: c.cniConfig,
config: confList,
ifName: getIfName(c.prefix, i),
})
i++
}
if len(c.networks) == 0 {
return errors.Wrapf(ErrCNINotInitialized, "no valid networks found in %s", c.pluginDirs)
if len(confList.Plugins) == 0 {
return errors.Wrapf(ErrInvalidConfig, "CNI config list %s has no networks, skipping", confFile)
}
networks = append(networks, &Network{
cni: c.cniConfig,
config: confList,
ifName: getIfName(c.prefix, i),
})
i++
if i == max {
break
}
return nil
}
if len(networks) == 0 {
return errors.Wrapf(ErrCNINotInitialized, "no valid networks found in %s", c.pluginDirs)
}
c.networks = append(c.networks, networks...)
return nil
}