github.com/john-lin/cni@v0.6.0-rc1.0.20170712150331-b69e640cc0e2/pkg/version/legacy_examples/example_runtime.go (about) 1 // Copyright 2016 CNI authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package legacy_examples 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os" 21 22 noop_debug "github.com/containernetworking/cni/plugins/test/noop/debug" 23 ) 24 25 // An ExampleRuntime is a small program that uses libcni to invoke a network plugin. 26 // It should call ADD and DELETE, verifying all intermediate steps 27 // and data structures. 28 type ExampleRuntime struct { 29 Example 30 NetConfs []string // The network configuration names to pass 31 } 32 33 type exampleNetConfTemplate struct { 34 conf string 35 result string 36 } 37 38 // NetConfs are various versioned network configuration files. Examples should 39 // specify which version they expect 40 var netConfTemplates = map[string]exampleNetConfTemplate{ 41 "unversioned": { 42 conf: `{ 43 "name": "default", 44 "type": "noop", 45 "debugFile": "%s" 46 }`, 47 result: `{ 48 "ip4": { 49 "ip": "1.2.3.30/24", 50 "gateway": "1.2.3.1", 51 "routes": [ 52 { 53 "dst": "15.5.6.0/24", 54 "gw": "15.5.6.8" 55 } 56 ] 57 }, 58 "ip6": { 59 "ip": "abcd:1234:ffff::cdde/64", 60 "gateway": "abcd:1234:ffff::1", 61 "routes": [ 62 { 63 "dst": "1111:dddd::/80", 64 "gw": "1111:dddd::aaaa" 65 } 66 ] 67 }, 68 "dns":{} 69 }`, 70 }, 71 "0.1.0": { 72 conf: `{ 73 "cniVersion": "0.1.0", 74 "name": "default", 75 "type": "noop", 76 "debugFile": "%s" 77 }`, 78 result: `{ 79 "cniVersion": "0.1.0", 80 "ip4": { 81 "ip": "1.2.3.30/24", 82 "gateway": "1.2.3.1", 83 "routes": [ 84 { 85 "dst": "15.5.6.0/24", 86 "gw": "15.5.6.8" 87 } 88 ] 89 }, 90 "ip6": { 91 "ip": "abcd:1234:ffff::cdde/64", 92 "gateway": "abcd:1234:ffff::1", 93 "routes": [ 94 { 95 "dst": "1111:dddd::/80", 96 "gw": "1111:dddd::aaaa" 97 } 98 ] 99 }, 100 "dns":{} 101 }`, 102 }, 103 } 104 105 func (e *ExampleRuntime) GenerateNetConf(name string) (*ExampleNetConf, error) { 106 template, ok := netConfTemplates[name] 107 if !ok { 108 return nil, fmt.Errorf("unknown example net config template %q", name) 109 } 110 111 debugFile, err := ioutil.TempFile("", "cni_debug") 112 if err != nil { 113 return nil, fmt.Errorf("failed to create noop plugin debug file: %v", err) 114 } 115 debugFilePath := debugFile.Name() 116 117 debug := &noop_debug.Debug{ 118 ReportResult: template.result, 119 } 120 if err := debug.WriteDebug(debugFilePath); err != nil { 121 os.Remove(debugFilePath) 122 return nil, fmt.Errorf("failed to write noop plugin debug file %q: %v", debugFilePath, err) 123 } 124 conf := &ExampleNetConf{ 125 Config: fmt.Sprintf(template.conf, debugFilePath), 126 debugFilePath: debugFilePath, 127 } 128 129 return conf, nil 130 } 131 132 type ExampleNetConf struct { 133 Config string 134 debugFilePath string 135 } 136 137 func (c *ExampleNetConf) Cleanup() { 138 os.Remove(c.debugFilePath) 139 } 140 141 // V010_Runtime creates a simple noop network configuration, then 142 // executes libcni against the the noop test plugin. 143 var V010_Runtime = ExampleRuntime{ 144 NetConfs: []string{"unversioned", "0.1.0"}, 145 Example: Example{ 146 Name: "example_invoker_v010", 147 CNIRepoGitRef: "c0d34c69", //version with ns.Do 148 PluginSource: `package main 149 150 import ( 151 "fmt" 152 "io/ioutil" 153 "net" 154 "os" 155 156 "github.com/containernetworking/cni/pkg/ns" 157 "github.com/containernetworking/cni/libcni" 158 ) 159 160 func main(){ 161 code := exec() 162 os.Exit(code) 163 } 164 165 func exec() int { 166 confBytes, err := ioutil.ReadAll(os.Stdin) 167 if err != nil { 168 fmt.Printf("could not read netconfig from stdin: %+v", err) 169 return 1 170 } 171 172 netConf, err := libcni.ConfFromBytes(confBytes) 173 if err != nil { 174 fmt.Printf("could not parse netconfig: %+v", err) 175 return 1 176 } 177 fmt.Printf("Parsed network configuration: %+v\n", netConf.Network) 178 179 if len(os.Args) == 1 { 180 fmt.Printf("Expect CNI plugin paths in argv") 181 return 1 182 } 183 184 targetNs, err := ns.NewNS() 185 if err != nil { 186 fmt.Printf("Could not create ns: %+v", err) 187 return 1 188 } 189 defer targetNs.Close() 190 191 ifName := "eth0" 192 193 runtimeConf := &libcni.RuntimeConf{ 194 ContainerID: "some-container-id", 195 NetNS: targetNs.Path(), 196 IfName: ifName, 197 } 198 199 cniConfig := &libcni.CNIConfig{Path: os.Args[1:]} 200 201 result, err := cniConfig.AddNetwork(netConf, runtimeConf) 202 if err != nil { 203 fmt.Printf("AddNetwork failed: %+v", err) 204 return 2 205 } 206 fmt.Printf("AddNetwork result: %+v", result) 207 208 // Validate expected results 209 const expectedIP4 string = "1.2.3.30/24" 210 if result.IP4.IP.String() != expectedIP4 { 211 fmt.Printf("Expected IPv4 address %q, got %q", expectedIP4, result.IP4.IP.String()) 212 return 3 213 } 214 const expectedIP6 string = "abcd:1234:ffff::cdde/64" 215 if result.IP6.IP.String() != expectedIP6 { 216 fmt.Printf("Expected IPv6 address %q, got %q", expectedIP6, result.IP6.IP.String()) 217 return 4 218 } 219 220 err = cniConfig.DelNetwork(netConf, runtimeConf) 221 if err != nil { 222 fmt.Printf("DelNetwork failed: %v", err) 223 return 5 224 } 225 226 err = targetNs.Do(func(ns.NetNS) error { 227 _, err := net.InterfaceByName(ifName) 228 if err == nil { 229 return fmt.Errorf("interface was not deleted") 230 } 231 return nil 232 }) 233 if err != nil { 234 fmt.Println(err) 235 return 6 236 } 237 238 return 0 239 } 240 `, 241 }, 242 }