diff --git a/pkg/server/helpers.go b/pkg/server/helpers.go index 0b03e2298..2efa2c95a 100644 --- a/pkg/server/helpers.go +++ b/pkg/server/helpers.go @@ -437,6 +437,6 @@ func getPodCNILabels(id string, config *runtime.PodSandboxConfig) map[string]str "K8S_POD_NAMESPACE": config.GetMetadata().GetNamespace(), "K8S_POD_NAME": config.GetMetadata().GetName(), "K8S_POD_INFRA_CONTAINER_ID": id, - "IgnoreUnknown": "1", + "IgnoreUnknown": "1", } } diff --git a/pkg/server/sandbox_run.go b/pkg/server/sandbox_run.go index b5818e9ca..6112a3ec2 100644 --- a/pkg/server/sandbox_run.go +++ b/pkg/server/sandbox_run.go @@ -505,6 +505,10 @@ func (c *criContainerdService) setupPod(id string, path string, config *runtime. if configs, ok := result.Interfaces[defaultIfName]; ok && len(configs.IPConfigs) > 0 { return configs.IPConfigs[0].IP.String(), nil } + // If it comes here then the result was invalid so destroy the pod network and return error + if err := c.teardownPod(id, path, config); err != nil { + logrus.WithError(err).Errorf("Failed to destroy network for sandbox %q", id) + } return "", fmt.Errorf("failed to find network info for sandbox %q", id) } diff --git a/pkg/server/sandbox_run_test.go b/pkg/server/sandbox_run_test.go index 223b4599a..3e55f24b7 100644 --- a/pkg/server/sandbox_run_test.go +++ b/pkg/server/sandbox_run_test.go @@ -21,8 +21,8 @@ import ( "testing" "github.com/containerd/cri/pkg/annotations" + cni "github.com/containerd/go-cni" "github.com/containerd/typeurl" - "github.com/cri-o/ocicni/pkg/ocicni" imagespec "github.com/opencontainers/image-spec/specs-go/v1" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" @@ -331,7 +331,7 @@ options timeout:1 func TestToCNIPortMappings(t *testing.T) { for desc, test := range map[string]struct { criPortMappings []*runtime.PortMapping - cniPortMappings []ocicni.PortMapping + cniPortMappings []cni.PortMapping }{ "empty CRI port mapping should map to empty CNI port mapping": {}, "CRI port mapping should be converted to CNI port mapping properly": { @@ -349,7 +349,7 @@ func TestToCNIPortMappings(t *testing.T) { HostIp: "126.125.124.123", }, }, - cniPortMappings: []ocicni.PortMapping{ + cniPortMappings: []cni.PortMapping{ { HostPort: 5678, ContainerPort: 1234, @@ -378,7 +378,7 @@ func TestToCNIPortMappings(t *testing.T) { HostIp: "126.125.124.123", }, }, - cniPortMappings: []ocicni.PortMapping{ + cniPortMappings: []cni.PortMapping{ { HostPort: 8765, ContainerPort: 4321, diff --git a/pkg/server/service.go b/pkg/server/service.go index 151d7bb51..3352da6a1 100644 --- a/pkg/server/service.go +++ b/pkg/server/service.go @@ -140,6 +140,11 @@ func NewCRIContainerdService(config criconfig.Config, client *containerd.Client) return nil, fmt.Errorf("failed to initialize cni: %v", err) } + // 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 { + logrus.WithError(err).Error("Failed to load cni during init, please check CRI plugin status before setting up network for pods") + } // prepare streaming server c.streamServer, err = newStreamServer(c, config.StreamServerAddress, config.StreamServerPort) if err != nil { diff --git a/pkg/server/testing/fake_cni_plugin.go b/pkg/server/testing/fake_cni_plugin.go index 3376d9646..b098bba62 100644 --- a/pkg/server/testing/fake_cni_plugin.go +++ b/pkg/server/testing/fake_cni_plugin.go @@ -17,166 +17,33 @@ limitations under the License. package testing import ( - "fmt" - "math/rand" - "strconv" - "sync" - "time" - - "github.com/containernetworking/cni/pkg/types" - "github.com/cri-o/ocicni/pkg/ocicni" + cni "github.com/containerd/go-cni" ) -// CalledDetail is the struct contains called function name and arguments. -type CalledDetail struct { - // Name of the function called. - Name string - // Argument of the function called. - Argument interface{} -} - // FakeCNIPlugin is a fake plugin used for test. -type FakeCNIPlugin struct { - sync.Mutex - called []CalledDetail - errors map[string]error - IPMap map[string]string -} - -// getError get error for call -func (f *FakeCNIPlugin) getError(op string) error { - err, ok := f.errors[op] - if ok { - delete(f.errors, op) - return err - } - return nil -} - -// InjectError inject error for call -func (f *FakeCNIPlugin) InjectError(fn string, err error) { - f.Lock() - defer f.Unlock() - f.errors[fn] = err -} - -// InjectErrors inject errors for calls -func (f *FakeCNIPlugin) InjectErrors(errs map[string]error) { - f.Lock() - defer f.Unlock() - for fn, err := range errs { - f.errors[fn] = err - } -} - -// ClearErrors clear errors for call -func (f *FakeCNIPlugin) ClearErrors() { - f.Lock() - defer f.Unlock() - f.errors = make(map[string]error) -} - -func (f *FakeCNIPlugin) appendCalled(name string, argument interface{}) { - call := CalledDetail{Name: name, Argument: argument} - f.called = append(f.called, call) -} - -// GetCalledNames get names of call -func (f *FakeCNIPlugin) GetCalledNames() []string { - f.Lock() - defer f.Unlock() - names := []string{} - for _, detail := range f.called { - names = append(names, detail.Name) - } - return names -} - -// GetCalledDetails get detail of each call. -func (f *FakeCNIPlugin) GetCalledDetails() []CalledDetail { - f.Lock() - defer f.Unlock() - // Copy the list and return. - return append([]CalledDetail{}, f.called...) -} - -// SetFakePodNetwork sets the given IP for given arguments. -func (f *FakeCNIPlugin) SetFakePodNetwork(podNetwork ocicni.PodNetwork, ip string) { - f.Lock() - defer f.Unlock() - f.IPMap[podNetwork.NetNS] = ip -} +type FakeCNIPlugin struct{} // NewFakeCNIPlugin create a FakeCNIPlugin. -func NewFakeCNIPlugin() ocicni.CNIPlugin { - return &FakeCNIPlugin{ - errors: make(map[string]error), - IPMap: make(map[string]string), - } +func NewFakeCNIPlugin() *FakeCNIPlugin { + return &FakeCNIPlugin{} } -// Name return the name of fake CNI plugin. -func (f *FakeCNIPlugin) Name() string { - return "fake-CNI-plugin" -} - -// SetUpPod setup the network of PodSandbox. -func (f *FakeCNIPlugin) SetUpPod(podNetwork ocicni.PodNetwork) (types.Result, error) { - f.Lock() - defer f.Unlock() - f.appendCalled("SetUpPod", podNetwork) - if err := f.getError("SetUpPod"); err != nil { - return nil, err - } - f.IPMap[podNetwork.NetNS] = generateIP() - // types.Result is unused. +// Setup setups the network of PodSandbox. +func (f *FakeCNIPlugin) Setup(id, path string, opts ...cni.NamespaceOpts) (*cni.CNIResult, error) { return nil, nil } -// TearDownPod teardown the network of PodSandbox. -func (f *FakeCNIPlugin) TearDownPod(podNetwork ocicni.PodNetwork) error { - f.Lock() - defer f.Unlock() - f.appendCalled("TearDownPod", podNetwork) - if err := f.getError("TearDownPod"); err != nil { - return err - } - _, ok := f.IPMap[podNetwork.NetNS] - if !ok { - return fmt.Errorf("failed to find the IP") - } - delete(f.IPMap, podNetwork.NetNS) +// Remove teardown the network of PodSandbox. +func (f *FakeCNIPlugin) Remove(id, path string, opts ...cni.NamespaceOpts) error { return nil } -// GetPodNetworkStatus get the status of network. -func (f *FakeCNIPlugin) GetPodNetworkStatus(podNetwork ocicni.PodNetwork) (string, error) { - f.Lock() - defer f.Unlock() - f.appendCalled("GetPodNetworkStatus", podNetwork) - if err := f.getError("GetPodNetworkStatus"); err != nil { - return "", err - } - ip, ok := f.IPMap[podNetwork.NetNS] - if !ok { - return "", fmt.Errorf("failed to find the IP") - } - return ip, nil -} - // Status get the status of the plugin. func (f *FakeCNIPlugin) Status() error { - f.Lock() - defer f.Unlock() - f.appendCalled("Status", nil) - return f.getError("Status") + return nil } -func generateIP() string { - rand.Seed(time.Now().Unix()) - p1 := strconv.Itoa(rand.Intn(266)) - p2 := strconv.Itoa(rand.Intn(266)) - p3 := strconv.Itoa(rand.Intn(266)) - p4 := strconv.Itoa(rand.Intn(266)) - return p1 + "." + p2 + "." + p3 + "." + p4 +// Load loads the network config. +func (f *FakeCNIPlugin) Load(opts ...cni.LoadOption) error { + return nil }