// Copyright 2016 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 legacy_examples // An ExampleRuntime is a small program that uses libcni to invoke a network plugin. // It should call ADD and DELETE, verifying all intermediate steps // and data structures. type ExampleRuntime struct { Example NetConfs []string // The network configuration names to pass } // NetConfs are various versioned network configuration files. Examples should // specify which version they expect var NetConfs = map[string]string{ "unversioned": `{ "name": "default", "type": "ptp", "ipam": { "type": "host-local", "subnet": "10.1.2.0/24" } }`, "0.1.0": `{ "cniVersion": "0.1.0", "name": "default", "type": "ptp", "ipam": { "type": "host-local", "subnet": "10.1.2.0/24" } }`, } // V010_Runtime creates a simple ptp network configuration, then // executes libcni against the currently-built plugins. var V010_Runtime = ExampleRuntime{ NetConfs: []string{"unversioned", "0.1.0"}, Example: Example{ Name: "example_invoker_v010", CNIRepoGitRef: "c0d34c69", //version with ns.Do PluginSource: `package main import ( "fmt" "io/ioutil" "net" "os" "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/libcni" ) func main(){ code := exec() os.Exit(code) } func exec() int { confBytes, err := ioutil.ReadAll(os.Stdin) if err != nil { fmt.Printf("could not read netconfig from stdin: %+v", err) return 1 } netConf, err := libcni.ConfFromBytes(confBytes) if err != nil { fmt.Printf("could not parse netconfig: %+v", err) return 1 } fmt.Printf("Parsed network configuration: %+v\n", netConf.Network) if len(os.Args) == 1 { fmt.Printf("Expect CNI plugin paths in argv") return 1 } targetNs, err := ns.NewNS() if err != nil { fmt.Printf("Could not create ns: %+v", err) return 1 } defer targetNs.Close() ifName := "eth0" runtimeConf := &libcni.RuntimeConf{ ContainerID: "some-container-id", NetNS: targetNs.Path(), IfName: ifName, } cniConfig := &libcni.CNIConfig{Path: os.Args[1:]} result, err := cniConfig.AddNetwork(netConf, runtimeConf) if err != nil { fmt.Printf("AddNetwork failed: %+v", err) return 2 } fmt.Printf("AddNetwork result: %+v", result) expectedIP := result.IP4.IP err = targetNs.Do(func(ns.NetNS) error { netif, err := net.InterfaceByName(ifName) if err != nil { return fmt.Errorf("could not retrieve interface: %v", err) } addrs, err := netif.Addrs() if err != nil { return fmt.Errorf("could not retrieve addresses, %+v", err) } found := false for _, addr := range addrs { if addr.String() == expectedIP.String() { found = true break } } if !found { return fmt.Errorf("Far-side link did not have expected address %s", expectedIP) } return nil }) if err != nil { fmt.Println(err) return 4 } err = cniConfig.DelNetwork(netConf, runtimeConf) if err != nil { fmt.Printf("DelNetwork failed: %v", err) return 5 } err = targetNs.Do(func(ns.NetNS) error { _, err := net.InterfaceByName(ifName) if err == nil { return fmt.Errorf("interface was not deleted") } return nil }) if err != nil { fmt.Println(err) return 6 } return 0 } `, }, }